我正在寻找一种将预处理器标记转换为字符串的方法。具体来说,我在某处得到了:
#define MAX_LEN 16
我想用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0 sscanf(buf, "%"MAX_LEN"s", val);
我愿意用其他方法来完成同样的事情,但只能用标准库。
zbwhf8kr1#
参见 Using FILE and LINE to Report Errors:
#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define AT __FILE__ ":" TOSTRING(__LINE__)
因此,您的问题可以通过执行sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);来解决。
sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);
axzmvihb2#
我在网上找到了答案。
#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; }
xoefb8l83#
这应该可以工作:
sscanf(buf, "%" #MAX_LEN "s", val);
如果没有,就需要“双膨胀”技巧:
#define STR1(x) #x #define STR(x) STR1(x) sscanf(buf, "%" STR(MAX_LEN) "s", val);
oyxsuwqo4#
应该使用双展开字符串化宏技巧。或者只是
#define MAX_LEN 16 #define MAX_LEN_S "16" char val[MAX_LEN+1]; sscanf(buf, "%"MAX_LEN_S"s", val);
并保持同步(这有点麻烦,但只要定义彼此相邻,你就可能记得。实际上,在这种特殊情况下,strncpy还不够吗?
strncpy
strncpy(val, buf, MAX_LEN); val[MAX_LEN] = '\0';
但是,如果是printf,这会更容易:
printf
sprintf(buf, "%.*s", MAX_LEN, val);
nzrxty8p5#
虽然前面的一些答案“工作”,但我个人建议只使用简单的字符串API,而不是libc中的dreck。有许多可移植的API,其中一些还进行了优化,以便于包含在您的项目中。而像ustr这样的一些具有微小的空间开销并支持堆栈变量。
gwbalxhn6#
在我的示例中,要生成的格式是%16s%16s%d:
%16s%16s%d
#include <iostream> #define MAX_LEN 16 #define AUX(x) #x #define STRINGIFY(x) AUX(x) int main() { char buffer[] = "Hello World 25"; char val[MAX_LEN+1]; char val2[MAX_LEN+1]; int val3; char format[] = "%" STRINGIFY(MAX_LEN) "s" "%" STRINGIFY(MAX_LEN) "s" "%d"; int result = sscanf(buffer, format, val, val2, &val3); std::cout<< val << std::endl; std::cout<< val2 << std::endl; std::cout<< val3 << std::endl; std::cout<<"Filled: " << result << " variables" << std::endl; std::cout << "Format: " << format << std::endl; }
输出
6条答案
按热度按时间zbwhf8kr1#
参见 Using FILE and LINE to Report Errors:
因此,您的问题可以通过执行
sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);
来解决。axzmvihb2#
我在网上找到了答案。
上面的不起作用,但希望说明我想做的,即。使VERSION_STRING结束为“v4.47”。
要生成正确的数字形式,请使用以下命令
xoefb8l83#
这应该可以工作:
如果没有,就需要“双膨胀”技巧:
oyxsuwqo4#
应该使用双展开字符串化宏技巧。或者只是
并保持同步(这有点麻烦,但只要定义彼此相邻,你就可能记得。
实际上,在这种特殊情况下,
strncpy
还不够吗?但是,如果是
printf
,这会更容易:nzrxty8p5#
虽然前面的一些答案“工作”,但我个人建议只使用简单的字符串API,而不是libc中的dreck。
有许多可移植的API,其中一些还进行了优化,以便于包含在您的项目中。而像ustr这样的一些具有微小的空间开销并支持堆栈变量。
gwbalxhn6#
在我的示例中,要生成的格式是
%16s%16s%d
:输出