代码之家  ›  专栏  ›  技术社区  ›  Throwback1986

C99宏在求值后生成带引号的字符串文字

  •  3
  • Throwback1986  · 技术社区  · 16 年前

    我正在C99中开发一个嵌入式应用程序,该项目包含一些整数常量,定义如下:

    #define LEVEL1     0x0000
    #define LEVEL2     (LEVEL1 + 1)
    

    以上版本。例如:

    strncpy(str, STRING(LEVEL2), len);
    

    strncpy(str, "0x0001", len);
    

    strncpy(str, "0001", len);
    

    使用带有#运算符的两级宏(如 this question )差不多可以了。它的计算结果是

    strncpy(str, "(LEVEL1 + 1)", len);
    

    我希望避免使用运行时函数—因此我尝试使用宏解决方案。建议?

    2 回复  |  直到 9 年前
        1
  •  2
  •   Igor Zevaka    15 年前

    由于预处理器stringizer是一个巨大的难题,因此在创建版本号和字符串化时,都需要添加一个间接级别:

    #define STRING1(s) #s
    #define STRING(s) STRING1(s)
    
    #define LEVEL(x) x
    #define LEVEL1 LEVEL(1)
    #define LEVEL2 LEVEL(2)
    
    printf(STRING(LEVEL2));
    //2
    
        2
  •  1
  •   schot    16 年前

    您不能这样做,因为预处理器对C语言一无所知,所以无法进行计算。

    我看到有两种方法可以得到想要的结果:

    人工评估

    完全按照您希望的方式编写级别,并使用单个stringizer操作符:

    #define LEVEL1 0x0000
    #define LEVEL2 0x0001
    #define STRING(x)   # x
    
    strncpy(str, STRING(LEVEL2), len);
    

    缺点是这容易出错,并且可能与本地编码约定冲突。

    运行时评估

    使用字符串格式函数之一 sprintf snprintf .

    #define LEVEL1 0x0000
    #define LEVEL2 0x0001
    
    char level[7];
    snprintf(level, sizeof level, "%#06x", LEVEL2);
    strncpy(str, level, len);
    

    这有您想要避免的运行时开销。