当前位置:  开发笔记 > 编程语言 > 正文

将预处理程序标记转换为字符串

如何解决《将预处理程序标记转换为字符串》经验,为你挑选了3个好方法。

我正在寻找一种方法将预处理器令牌转换为字符串.

具体来说,我在某处得到了:

#define MAX_LEN 16

我想用它来防止缓冲区溢出:

char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);

我愿意通过其他方式来完成同样的事情,但仅限标准库.



1> Dan..:

具体请参见http://www.decompile.com/cpp/faq/file_and_line_error_string.htm:

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)

所以你的问题可以通过这样做来解决 sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);


@Daniel Brunner单个宏将粘贴令牌本身,字面意思是"%""MAX_LEN""%"`第二个宏导致令牌*值*被粘贴,例如,"16"`因为`TOSTRING`宏使最终代码等同于`STRINGIFY(16)`.
为什么级联2个宏?不是一个足够的TOSTRING?

2> davenpcj..:

我在网上找到了答案.

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR

以上不起作用,但希望说明我想做什么,即使VERSION_STRING结束为"v4.47".

要生成正确的数字形式,请使用类似的内容

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
#define VERSION_STRING "v" STRINGIZE(VERSION_MAJOR) \
"." STRINGIZE(VERSION_MINOR)

#include 
int main() {
    printf ("%s\n", VERSION_STRING);
    return 0;
}



3> James Curran..:

已经有一段时间了,但这应该有效:

 sscanf(buf, "%" #MAX_LEN "s", val);

如果没有,它将需要"双扩展"技巧:

 #define STR1(x)  #x
 #define STR(x)  STR1(x)
 sscanf(buf, "%" STR(MAX_LEN) "s", val);


第一个无效;#将宏扩展中的宏参数字符串化。第二个将起作用。
推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有