Link to home
Start Free TrialLog in
Avatar of gil_mo
gil_mo

asked on

Need a macro that converts into wide-char string...

In one of the include files of my program, I have the following:

#define Str4 "1234"

I'm now looking for a macro that would convert this into a wide-character string. The macro should look like this:

#define WIDE(S) <Macro implementation...>

and then, WIDE(Str4) would expand to L"1234".

How do I do it??

Special note: Please avoid posting comments or suggestions that you havn't tested, like most postings below (until Jan-24)
Avatar of jkr
jkr
Flag of Germany image

The most common approach (and indeed what MS uses) is to

#define WIDE(s) L##s

(see

#define __T(x)      L ## x

in 'tchar.h' - BTW: '##' is called the 'merging operator')

Feel free to ask if you need more information!
Avatar of gil_mo
gil_mo

ASKER

jkr, WIDE(Str4) simply pastes L to Str4 to yield LStr4 rather than L"1234".
Avatar of gil_mo

ASKER

(see my comment)
Hi gil_mo,

couldn't you simply call something like:

'L Str4'

There is (AFAIK) no difference between
'L"1234"' and
'L "1234"'...

ZOPPO
#define Str4 WIDE("1234")
Avatar of gil_mo

ASKER

Zoppo, there *is* a difference (wouldn't compile with an extra space. Besides, how would you insert the space using the macro?).

jkr, oooooh my, you are suggesting that I replace the definition of Str4 with another! There are many places in the code where I use Str4 as it is now - it would cease to work!
wow, jkr, how did you do that? You added one comment and I recieved 18 (!) notification eMails   ;-\
Avatar of gil_mo

ASKER

(me too! something was baaaaad with E-E for a while there)
well, gil_mo, you're right, there's a difference ... so, only solution I see now is something like:

#ifdef I_WANNA_USE_UNICODE
#define WIDE(s) L##s
#else
#define WIDE(s) s
#endif

#define Str4 WIDE("1234")
...

and define I_WANNA_USE_UNICODE wherever you want it...

ZOPPO
Avatar of gil_mo

ASKER

mmmm...  no decent answer for a couple of days now, me wonder... Could it be I found a limitation in the C language?
C doesn't have many limitations, try this:

#define Str4 "1234"
#define WIDE(S) L#S  // Single # char instead of double

main()
{
  WIDE(Str4) // would expand to L"1234"
}
Avatar of gil_mo

ASKER

No, zebada, it expands to L"Str4". Did you try it out before posting your comment?
I tested it but obviously I was suffering from "brain fade" - sorry about that :(
ASKER CERTIFIED SOLUTION
Avatar of zebada
zebada

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I was also thinking about this way of doing it, but never having used wide strings I am not familiar with the syntax used to declare them so this suggestion may be completely wrong:

However I assume that (expr) is equivalent to expr as described by the C definition of an expression.

#define Str4 "1234"
#define WIDE(S) L(S)

main()
{
  WIDE(Str4) // would expand to L("1234")
}

Avatar of gil_mo

ASKER

zebada, I'll buy your compiler for a million if it is so magnificant as to compile any of your suggestions.
You can send the million to my swiss bank account

#include <stdio.h>

#define Str4 "1234"
#define x(dummy) L
#define WIDE(S) x(dummy)S

main()
{
  int i;

  wchar_t *s;

  s = WIDE(Str4);
  for ( i=0 ; i<4 ; i++,s++ )
    printf("%d\n",*s);
}


Here's the *.i preprocessor output:

main()
{
  int i;

  wchar_t *s;

  s = L"1234";
  for ( i=0 ; i<4 ; i++,s++ )
    printf("%d\n",*s);
}

gil_mo: zebada's suggestion works great in VC++ 6, and should work fine in any compiler. x(dummy) isn't the greates name and parameter - something like WIDE2() might be better - but it works right.
Avatar of gil_mo

ASKER

Zebada, my apologies and a million is on its way.
Your solution doesn't compile with my *real* case (here I gave only a simplified case):

#define P_VERSION "1.0"
#define P_CODE "D" P_VERSION  // Haa! concatenated string...

wcscpy(wStr, WIDE(P_CODE));

Anyway, you deserve the points, if you have an additional insight regarding the real situation, please tell.

I've never heard of *.i files - how do I generate them?
This won't work at all, because you're #define-ing P_CODE to be
"D" "1.0"

Notice that you cannot do
L"D" "1.0"
even directly, because the L applies only to the first string. You have to do
L"D" L"1.0"

So what to do depends on what you need to not change...

If it's going to be concatenated, you have to have the L modifier on each string, so you need to change the #define.

Maybe something like this:

#define P_VERSION "1.0"
#define P_CODE L"D" WIDE(P_VERSION)

wcscpy(wStr, P_CODE);

But it seems you probably want your code to be an'e to do something like this:

wcscpy(wStr, WIDE(P_CODE));
strcpy(str, P_CODE);

There is unfortunately no way to do this, because the L modifier works only on single strings as I mentioned. You can have two defines:

#define P_VERSION "1.0"
#define P_CODE "D" P_VERSION
#define P_WCODE L"D" WIDE(P_VERSION)

wcscpy(wStr, P_WCODE);
strcpy(str, P_CODE);

Or you can not use concatenation:

#define P_CODE "D1.0"

wcscpy(wStr, WIDE(P_CODE));
strcpy(str, P_CODE);

Or you can use actual conversion functions:

MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, P_CODE, strlen(P_CODE), wStr, 256);
(instead of wcscpy, this is a Win function, other platforms may be different or you may have to write your own)

Avatar of gil_mo

ASKER

conchita, thanks for your insights.