Предположим, у вас есть массив строк:
const char str1[] = "some/path";
const char str2[] = "another/path";
const char str3[] = "and/a/third/path";
const char* strs[3];
strs[0] = str1;
strs[1] = str2;
strs[2] = str3;
Сохраняя исходные определения строк (т. Е. str1
, str2
и str3
), я хотел бы иметь возможность изменять пути в массиве одним символом в управление директивой препроцессора. Простейший способ, который я нашел для этого, - это удалить квалификатор const
, добавить лишний нулевой байт и сдвинуть каждый элемент вправо.
char str1[] = "some/path\0";
char str2[] = "another/path\0";
char str3[] = "and/a/third/path\0";
char* strs[3];
strs[0] = str1;
strs[1] = str2;
strs[2] = str3;
#ifdef build_option
for(int i=0; i<3; i++) {
for(int j=strlen(strs[i]); j>=0; j--) {
strs[i][j] = strs[i][j-1];
}
strs[i][0] = '.'; // prepend each path with this character
}
#endif
fprintf(stdout, "%s\n%s\n%s\n", strs[0], strs[1], strs[2]);
Выход:
.some/path
.another/path
.and/a/third/path
Это работает достаточно хорошо, но мне интересно, есть ли более простой или более идиоматический способ сделать то же самое, предпочтительно статически (хотя это не обязательно).
редактирует:
Чтобы прояснить сценарий, требуется только исходная строка в первичном маршруте компиляции; в менее используемом альтернативном пути компиляции требуются как исходные, так и измененные строки. На последнем маршруте измененная форма является основной и выполняет ту же роль, что и оригинал во всей программе (однако доступ к оригиналу по-прежнему необходим).
Спасибо всем за множество замечательных предложений; их комбинация использовалась для получения следующего:
#include <stdio.h>
//#define build_option // rare compilation route
#ifdef build_option
#define STR_OFFSET 0
#else
#define STR_OFFSET 1
#endif
int
main(int argc, char *argv[])
{
const char str1[] = ".some/path";
const char str2[] = ".another/path";
const char str3[] = ".and/a/third/path";
const char* strs[3] = { str1,
str2,
str3 };
for(int i=0; i<3; i++)
fprintf(stdout, "%s\n",strs[i]+STR_OFFSET);
#ifdef build_option
fprintf(stdout, "\noriginal:\n");
for(int i=0; i<3; i++)
fprintf(stdout, "%s\n",strs[i]+1);
#endif
return 0;
}
Без определения build_option
это дает
some/path
another/path
and/a/third/path
С определением build_option
это дает
.some/path
.another/path
.and/a/third/path
original:
some/path
another/path
and/a/third/path