将预处理程序标记转换为字符串
-
04-07-2019 - |
题
我正在寻找一种将预处理程序令牌转换为字符串的方法。
具体来说,我在某个地方得到了:
#define MAX_LEN 16
我希望用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
我愿意采用其他方式来完成同样的事情,但仅限标准库。
解决方案
请参阅 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);
其他提示
我在网上找到了答案。
#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 <stdio.h> int main() { printf ("%s\n", VERSION_STRING); return 0; }
已经有一段时间了,但这应该有效:
sscanf(buf, "%" #MAX_LEN "s", val);
如果没有,则需要“双重扩张”。特技:
#define STR1(x) #x
#define STR(x) STR1(x)
sscanf(buf, "%" STR(MAX_LEN) "s", val);
您应该使用双扩展字符串化技巧。或者只是有一个
#define MAX_LEN 16
#define MAX_LEN_S "16"
char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);
并保持同步。 (这有点麻烦,但只要定义彼此相邻,你可能会记得。)
实际上,在这种特殊情况下,不会 strncpy
吗?
strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';
如果它是 printf
,那么这将更容易:
sprintf(buf, "%.*s", MAX_LEN, val);
虽然上面的一些“工作”,但我个人建议只使用简单的字符串API而不是libc中的dreck。有许多便携式API,其中一些也经过优化,易于包含在您的项目中......还有一些像 ustr 具有很小的空间开销并支持堆栈变量。
不隶属于 StackOverflow