Convert a preprocessor token to a string

CC PreprocessorStringification

C Problem Overview


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.

C Solutions


Solution 1 - C

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 - C

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 > int main() { > printf ("%s\n", VERSION_STRING); > return 0; > }

Solution 3 - C

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 - C

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);

Solution 5 - C

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 http://www.and.org/ustr/">ustr</a> have tiny space overhead and support for stack variables.

Solution 6 - C

My two cents.

#define MAX_LEN 16

#define AUX_VALUE(x) x
#define QUOTATION_VALUE() "
#define STRINGIFY(x) #x //Ok in all.
//#define STRINGIFY(x) QUOTATION_VALUE()AUX_VALUE(x)QUOTATION_VALUE() //Ok only in VC++

std::string str = STRINGIFY(MAX_LEN);
const char* str2 = STRINGIFY(MAX_LEN);
sscanf(buf, "%" STRINGIFY(MAX_LEN) "s", val);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondavenpcjView Question on Stackoverflow
Solution 1 - CDanView Answer on Stackoverflow
Solution 2 - CdavenpcjView Answer on Stackoverflow
Solution 3 - CJames CurranView Answer on Stackoverflow
Solution 4 - CephemientView Answer on Stackoverflow
Solution 5 - CJames AntillView Answer on Stackoverflow
Solution 6 - CJomaView Answer on Stackoverflow