0

It is a well-known fact that to print values of variables that type is one of fixed width integer types (like uint32_t) you need to include cinttypes (in C++) or inttypes.h (in C) header file and to use format specifiers macros like PRIu32. But how to do the same thing when wprintf function is used? Such macro should expand as a string literal with L prefix in that case.

Constructor
  • 7,273
  • 2
  • 24
  • 66
  • 2
    In which of C and C++ are you programming? Please choose at most one. – fuz Apr 29 '16 at 13:48
  • 1
    @FUZxxl Why should I choose only one? – Constructor Apr 29 '16 at 13:51
  • 1
    What's the actual problem ? Does your code not compile ? Does `wprintf` display something else than you expect ? – Jabberwocky Apr 29 '16 at 13:52
  • 1
    Because usually the answer is different, but perhaps not in this case. Also, using`printf()` is not so common in [tag:c++] programs, use `` and it deals with all this. – Iharob Al Asimi Apr 29 '16 at 13:52
  • @MichaelWalz Yes, of course. `wprintf` accepts only wide character string as a format string. – Constructor Apr 29 '16 at 13:54
  • 1
    @iharob I think in this case there is no difference. And yes, it is not so common to use `printf` in C++, but it may be useful in several cases. – Constructor Apr 29 '16 at 13:57
  • @Constructor I know, that's why I like [tag:c] more. – Iharob Al Asimi Apr 29 '16 at 13:57
  • 1
    Can you post an example that fails to compile? I just don't see the need for a wide character version of `PRIu32`. – cremno Apr 29 '16 at 13:59
  • @Constructor A question asking for code in more than one programming language is too broad. Either narrow it down to only one language or watch your question getting closed. – fuz Apr 29 '16 at 14:06
  • @FUZxxl There are [more than 30.000 such questions at SO](http://stackoverflow.com/questions/tagged/c%2b%2b%20c). Only for C++/C pair of languages. – Constructor Apr 29 '16 at 14:12
  • @Constructor I don't have enough time to enforce the rules on all questions and some times (but not here), the tag combination is correct. I recommend you however, to stick to them. Questions should be about one language, except if they are about the interaction between multiple languages. – fuz Apr 29 '16 at 14:14

4 Answers4

5

If this will work or not actually depends on which standard of C the compiler is using.

From this string literal reference

Only two narrow or two wide string literals may be concatenated. (until C99)

and

If one literal is unprefixed, the resulting string literal has the width/encoding specified by the prefixed literal. If the two string literals have different encoding prefixes, concatenation is implementation-defined. (since C99)

[Emphasis mine]

So if you're using an old compiler or one that doesn't support the C99 standard (or later) it's not possible. Besides fixed-width integer types was standardized in C99 so the macros don't really exist for such old compilers, making the issue moot.

For more modern compilers which support C99 and later, it's a non-issue since the string-literal concatenation will work and the compiler will turn the non-prefixed string into a wide-character string, so doing e.g.

wprintf(L"Value = %" PRIu32 "\n", uint32_t_value);

will work fine.


If you have a pre-C99 compiler, but still have the macros and fixed-width integer types, you can use function-like macros to prepend the L prefix to the string literals. Something like

#define LL(s) L ## s
#define L(s) LL(s)

...

wprintf(L"Value = %" L(PRIu32) L"\n", uint32_t_value);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
3

Not sure where the problem is, but here (VS 2015) both

wprintf(L"AA %" PRIu32 L" BB", 123);

and

printf("AA %" PRIu32 " BB", 123);

compile correctly and give following output:

AA 123 BB
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
1

Even if your compiler does not support concatenation of differently-prefixed literals, you can always widen a narrow one:

#define WIDE(X) WIDE2(X)
#define WIDE2(X) L##X

wprintf(L"%" WIDE(PRIu32), foo);

Demo

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
1

A (weaker) alternative to using the macros from <inttypes.h> is to convert/cast the the fixed width type to an equivalent or larger standard type.

wprintf(L"%lu\n", 0ul + some_uint32_t_value);
// or 
wprintf(L"%lu\n", (unsigned long) some_uint32_t_value);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256