C 预处理器:动态 const char
C Preprocessor: dynamic const char
我想在编译时动态创建一个 const char
,如下所示:
const char reprx[] = "repr1[=10=]repr2[=10=]repr3[=10=]repr4[=10=]";
并使用 #define 指定字符串 reprX[=13=]
在字符串中重复的次数(通过将 X 替换为增量值)。例如 5:
const char reprx[] = "repr1[=11=]repr2[=11=]repr3[=11=]repr4[=11=]repr5[=11=]";
有简单的方法吗? (没有额外的库)
这可以给你一个线索:
#include <stdio.h>
#define repeat1(s) s"1[=10=]"
#define repeat2(s) repeat1(s)s"2[=10=]"
#define repeat3(s) repeat2(s)s"3[=10=]"
#define repeat4(s) repeat3(s)s"4[=10=]"
#define repeat5(s) repeat4(s)s"5[=10=]"
#define repeat6(s) repeat5(s)s"6[=10=]"
#define repeat7(s) repeat6(s)s"7[=10=]"
#define repeat8(s) repeat7(s)s"8[=10=]"
#define repeat9(s) repeat8(s)s"9[=10=]"
#define repeat(s, n) repeat##n(s)
int main(void)
{
printf("%s\n", repeat("repr", 5));
return 0;
}
输出:
printf("%s\n", "repr""1[=11=]""repr""2[=11=]""repr""3[=11=]""repr""4[=11=]""repr""5[=11=]");
请注意,此版本限制为 9 个字符串。
执行此操作的最简单方法是使用自定义预处理脚本,您可以将其集成到构建过程中。
我不知道你有什么工具可用,但你可以轻松地使用 awk
作为预处理器。如果您正在使用 make
,您可以从框架自动构建 c
文件:(请参阅下面的原始 awk 脚本。)
file.c: file.c.in
awk ' \
/^#define X / { \
for (i = 1; i <= $; ++i) \
s = s "\"repr"i"\0\"" \
} \
match($[=10=], / *const char \*reprx\[\] = /) { \
$[=10=] = substr($[=10=], 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[=11=]""repr2[=11=]""repr3[=11=]""repr4[=11=]""repr5[=11=]""repr6[=11=]""repr7[=11=]";
/* The rest of the program */
由于需要转义美元符号和行尾,所以有点模糊,这里是原始的 awk 程序:
awk '/^#define X / {
for (i = 1; i <= ; ++i)
s = s "\"repr"i"\0\""
}
match([=12=], / *const char \*reprx\[\] = /) {
[=12=] = substr([=12=], 1, RLENGTH) s ";"
}
1'
我想在编译时动态创建一个 const char
,如下所示:
const char reprx[] = "repr1[=10=]repr2[=10=]repr3[=10=]repr4[=10=]";
并使用 #define 指定字符串 reprX[=13=]
在字符串中重复的次数(通过将 X 替换为增量值)。例如 5:
const char reprx[] = "repr1[=11=]repr2[=11=]repr3[=11=]repr4[=11=]repr5[=11=]";
有简单的方法吗? (没有额外的库)
这可以给你一个线索:
#include <stdio.h>
#define repeat1(s) s"1[=10=]"
#define repeat2(s) repeat1(s)s"2[=10=]"
#define repeat3(s) repeat2(s)s"3[=10=]"
#define repeat4(s) repeat3(s)s"4[=10=]"
#define repeat5(s) repeat4(s)s"5[=10=]"
#define repeat6(s) repeat5(s)s"6[=10=]"
#define repeat7(s) repeat6(s)s"7[=10=]"
#define repeat8(s) repeat7(s)s"8[=10=]"
#define repeat9(s) repeat8(s)s"9[=10=]"
#define repeat(s, n) repeat##n(s)
int main(void)
{
printf("%s\n", repeat("repr", 5));
return 0;
}
输出:
printf("%s\n", "repr""1[=11=]""repr""2[=11=]""repr""3[=11=]""repr""4[=11=]""repr""5[=11=]");
请注意,此版本限制为 9 个字符串。
执行此操作的最简单方法是使用自定义预处理脚本,您可以将其集成到构建过程中。
我不知道你有什么工具可用,但你可以轻松地使用 awk
作为预处理器。如果您正在使用 make
,您可以从框架自动构建 c
文件:(请参阅下面的原始 awk 脚本。)
file.c: file.c.in
awk ' \
/^#define X / { \
for (i = 1; i <= $; ++i) \
s = s "\"repr"i"\0\"" \
} \
match($[=10=], / *const char \*reprx\[\] = /) { \
$[=10=] = substr($[=10=], 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[=11=]""repr2[=11=]""repr3[=11=]""repr4[=11=]""repr5[=11=]""repr6[=11=]""repr7[=11=]";
/* The rest of the program */
由于需要转义美元符号和行尾,所以有点模糊,这里是原始的 awk 程序:
awk '/^#define X / {
for (i = 1; i <= ; ++i)
s = s "\"repr"i"\0\""
}
match([=12=], / *const char \*reprx\[\] = /) {
[=12=] = substr([=12=], 1, RLENGTH) s ";"
}
1'