问题
I'm looking for a way to convert a preprocessor token to a string.
Specifically, I've somewhere got:
#define MAX_LEN 16
and I want to use it to prevent buffer overrun:
char val[MAX_LEN+1]; // room for \0
sscanf(buf, "%"MAX_LEN"s", val);
I'm open to other ways to accomplish the same thing, but standard library only.
回答1:
see http://www.decompile.com/cpp/faq/file_and_line_error_string.htm specifically:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
so your problem can be solved by doing
sscanf(buf, "%" TOSTRING(MAX_LEN) "s", val);
回答2:
I found an answer online.
#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; }
回答3:
It's been a while, but this should work:
sscanf(buf, "%" #MAX_LEN "s", val);
If not, it'll need to "double expansion" trick:
#define STR1(x) #x
#define STR(x) STR1(x)
sscanf(buf, "%" STR(MAX_LEN) "s", val);
回答4:
You should use the double-expansion stringification macro trick. Or just have a
#define MAX_LEN 16
#define MAX_LEN_S "16"
char val[MAX_LEN+1];
sscanf(buf, "%"MAX_LEN_S"s", val);
and keep it in sync. (That's a bit of a bother, but as long as the definitions are right next to each other, you'll probably remember.)
Actually, in this particular case, wouldn't strncpy
suffice?
strncpy(val, buf, MAX_LEN);
val[MAX_LEN] = '\0';
If it were printf
, though, this would be easier:
sprintf(buf, "%.*s", MAX_LEN, val);
回答5:
While some of the above "work", personally I'd recommend just using a simple string API instead of the dreck that comes in libc. There are a number of portable APIs, some of which are also optimized for ease of inclusion in your project ... and some like ustr have tiny space overhead and support for stack variables.
来源:https://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string