我正在寻找一种将预处理器标记转换为字符串的方法。
具体而言,我有一个这样的标记:
#define MAX_LEN 16
我想使用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
我愿意尝试其他实现方式,但只能使用标准库。
我正在寻找一种将预处理器标记转换为字符串的方法。
具体而言,我有一个这样的标记:
#define MAX_LEN 16
我想使用它来防止缓冲区溢出:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
我愿意尝试其他实现方式,但只能使用标准库。
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
所以您的问题可以通过执行以下代码来解决:sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);
。
"%" "MAX_LEN" "%"
。第二个宏会导致令牌值被粘贴,例如"16"
,因为TOSTRING
宏使最终代码等效于STRINGIFY(16)
。 - Tim Sylvester我在网上找到了一个答案。(https://gcc.gnu.org/onlinedocs/gcc-3.4.3/cpp/Stringification.html)
#define VERSION_MAJOR 4 #define VERSION_MINOR 47 #define VERSION_STRING "v" #VERSION_MAJOR "." #VERSION_MINOR
The above does not work but hopefully illustrates what I would like to do, i.e. make VERSION_STRING end up as "v4.47".
To generate the proper numeric form use something like
#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);
#
只将宏参数转换为字符串,而第一行不在宏的主体内。 - Jonathan Leffler#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);
%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;
}
输出