C预处理器:动态const char

时间:2015-09-23 15:08:26

标签: c arm microcontroller c-preprocessor gcc4.7

我想在编译时动态创建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 个答案:

答案 0 :(得分:3)

这可以给你一个线索:

#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个字符串。

答案 1 :(得分:1)

最简单的方法是使用自定义预处理脚本,您可以将其集成到构建过程中。

我不知道您有哪些可用的工具,但您可以轻松地使用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'