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

dav*_*pcj 60 c stringification c-preprocessor

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

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

#define MAX_LEN 16
Run Code Online (Sandbox Code Playgroud)

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

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

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

Dan*_*Dan 102

具体请参见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__)
Run Code Online (Sandbox Code Playgroud)

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

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

dav*_*pcj 21

我在网上找到了答案.

#define VERSION_MAJOR 4
#define VERSION_MINOR 47

#define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
Run Code Online (Sandbox Code Playgroud)

以上不起作用,但希望说明我想做什么,即使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 <stdio.h>
int main() {
    printf ("%s\n", VERSION_STRING);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 回复*“我在网上找到了答案。”*:您能提供参考吗?相关:*[剽窃标记和版主工具已在 Stack Overflow 上发布!](https://meta.stackoverflow.com/questions/423749/)* (2认同)

Jam*_*ran 7

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

 sscanf(buf, "%" #MAX_LEN "s", val);
Run Code Online (Sandbox Code Playgroud)

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

 #define STR1(x)  #x
 #define STR(x)  STR1(x)
 sscanf(buf, "%" STR(MAX_LEN) "s", val);
Run Code Online (Sandbox Code Playgroud)

  • 第一个无效;#将宏扩展中的宏参数字符串化。第二个将起作用。 (2认同)