Convert a preprocessor token to a string
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.
Solution 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);
Solution 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; }
Solution 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);
Solution 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);