4

Possible Duplicate:
Convert a preprocessor token to a string

#define num 1234

I want to define a "const char*" based on num, in the sample it would be:

#define num_str "1234"

Can I write a macro statement to achieve this? NB: 1234 would be changed.

Thanks.

Community
  • 1
  • 1
user1787726
  • 65
  • 1
  • 3

2 Answers2

3

Yes you can, but the macro substitution can get a little strange-looking. The double-macro substitution is there for a reason, and if you think about it for awhile, it will become clear why it is needed.

#define STRINGIZER_(exp)   #exp
#define STRINGIZER(exp)    STRINGIZER_(exp)
#define NUM 1234

int main(int argc, char *argv[])
{
    const char *p = STRINGIZER(NUM);
    printf("%s\n",p);
    return EXIT_SUCCESS;
}

Running this:

1234

The reason for the double substitution: At first glance one may think this will solve the problem:

#define STRINGIZER(exp)    #exp
#define NUM 1234

int main(int argc, char *argv[])
{
    const char *p = STRINGIZER(NUM);
    printf("%s\n",p);
    return EXIT_SUCCESS;
}

But this produces:

NUM

which is not what we're trying to do. If you want the actual expansion of the NUM macro first then that is what you have to do: force the expansion. By forcing the preprocessor to substitute first through an intermediate expansion (as I show at the top of this answer) the passed-in macro is expanded first, then string-ized.

Side Bar: This technique is particularly useful for generating wide-char versions of predefined preprocessor macros that otherwise hold regular strings. For example, the __FILE__ macro. Suppose you wanted a wide-char version of this (a string prepended with 'L') You may first think this will work:

#define WIDESTR(str)    L##str

but expanding this with __FILE__ as in:

const wchar *p = WIDESTR(__FILE__);

will result in a compiler error: "Undefined identifier: L__FILE__"

So how can we address this? The same way we did above.

#define WIDESTR_(str)       L##str
#define WIDESTR(str)        WIDESTR_(str)

int main(int argc, char *argv[])
{
    const wchar_t* p = WIDESTR(__FILE__);
    wcout << p << endl;
    return EXIT_SUCCESS;
}

On my system, this produces:

/Users/craig/tmp/main/main/test.cpp

In Closing...

As a consolation prize, we combine everything in this answer into one giant goo-pile, what do we suppose happens when we do this:

int main()
{
    const wchar_t *p = WIDESTR(STRINGIZE(NUM));
    wcout << p << endl;
    return EXIST_SUCCESS;
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
0

How will the string be used in the rest of your code? Does it have to be a string macro? The standard way to create strings from other values is using sprintf() from string.h

#define num 1234
sprintf(string,"%d",num);
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
Ryan Tennill
  • 156
  • 7