Препроцессор C: динамический const char
Я хотел бы создать динамически const char
во время компиляции следующим образом:
const char reprx[] = "repr1\0repr2\0repr3\0repr4\0";
и с помощью #define указать количество раз, когда строка reprX\0
повторяется внутри строки (путем замены X на значение приращения). Например для 5:
const char reprx[] = "repr1\0repr2\0repr3\0repr4\0repr5\0";
Есть ли простой способ сделать это? (без дополнительных библиотек)
2 ответа
Это может дать вам подсказку:
#include <stdio.h>
#define repeat1(s) s"1\0"
#define repeat2(s) repeat1(s)s"2\0"
#define repeat3(s) repeat2(s)s"3\0"
#define repeat4(s) repeat3(s)s"4\0"
#define repeat5(s) repeat4(s)s"5\0"
#define repeat6(s) repeat5(s)s"6\0"
#define repeat7(s) repeat6(s)s"7\0"
#define repeat8(s) repeat7(s)s"8\0"
#define repeat9(s) repeat8(s)s"9\0"
#define repeat(s, n) repeat##n(s)
int main(void)
{
printf("%s\n", repeat("repr", 5));
return 0;
}
Выход:
printf("%s\n", "repr""1\0""repr""2\0""repr""3\0""repr""4\0""repr""5\0");
Обратите внимание, что эта версия ограничена 9 строками.
Простейший способ сделать это - использовать пользовательский сценарий предварительной обработки, который вы можете интегрировать в процесс сборки.
Я не знаю, какие инструменты у вас есть в наличии, но вы могли бы легко использовать awk
в качестве препроцессора. Если вы используете make
Вы могли бы построить c
файл автоматически из скелета: (См. ниже для оригинального сценария awk.)
file.c: file.c.in
awk ' \
/^#define X / { \
for (i = 1; i <= $$3; ++i) \
s = s "\"repr"i"\\0\"" \
} \
match($$0, / *const char \*reprx\[\] = /) { \
$$0 = substr($$0, 1, RLENGTH) s ";" \
} \
1' $^ > $@
Пример:
$ cat file.c.in
/* The beginning of the program */
#define X 7
/* Some part of the program */
const char *reprx[] = "Will be replaced";
/* The rest of the program */
$ make -s file.c
$ cat file.c
/* The beginning of the program */
#define X 7
/* Some part of the program */
const char *reprx[] = "repr1\0""repr2\0""repr3\0""repr4\0""repr5\0""repr6\0""repr7\0";
/* The rest of the program */
Так как это немного затенено необходимостью избегать знаков доллара и концов строк, вот оригинальная программа awk:
awk '/^#define X / {
for (i = 1; i <= $3; ++i)
s = s "\"repr"i"\\0\""
}
match($0, / *const char \*reprx\[\] = /) {
$0 = substr($0, 1, RLENGTH) s ";"
}
1'