众所周知,要打印类型为固定宽度整数类型(如uint32_t
)的变量的值,需要包含cinttypes
(在C++中)或inttypes.h
(在C中)头文件,并使用PRIu32
等格式说明符宏。但是当使用wprintf
函数时,如何做同样的事情呢?在这种情况下,这样的宏应该扩展为前缀为L
的字符串文字。
这是否有效实际上取决于编译器使用的C标准。
从这个字符串文字参考
只能连接两个窄字符串或两个宽字符串文字。(直到C99)
和
如果一个文字是不固定的,则生成的字符串文字具有前缀文字指定的宽度/编码。如果两个字符串文字具有不同的编码前缀,则级联是实现定义的。(自C99以来)
[强调矿]
因此,如果您使用的是旧编译器或不支持C99标准(或更高版本)的编译器,则这是不可能的。此外,C99中对固定宽度整数类型进行了标准化,因此对于这种旧编译器来说,宏并不真正存在,这使得问题变得毫无意义。
对于支持C99及更高版本的现代编译器来说,这是一个没有问题的问题,因为字符串文字连接将起作用,并且编译器将把无前缀字符串变成宽字符串,所以这样做例如
wprintf(L"Value = %" PRIu32 "n", uint32_t_value);
会很好用的。
如果您有C99之前的编译器,但仍然有宏和固定宽度整数类型,则可以使用类似函数的宏在字符串文字前面加上L
前缀。类似的东西
#define LL(s) L ## s
#define L(s) LL(s)
...
wprintf(L"Value = %" L(PRIu32) L"n", uint32_t_value);
不确定问题出在哪里,但这里(VS 2015)两个
wprintf(L"AA %" PRIu32 L" BB", 123);
和
printf("AA %" PRIu32 " BB", 123);
正确编译并给出以下输出:
AA 123 BB
即使您的编译器不支持不同前缀文字的串联,您也可以始终加宽一个窄的:
#define WIDE(X) WIDE2(X)
#define WIDE2(X) L##X
wprintf(L"%" WIDE(PRIu32), foo);
演示
使用<inttypes.h>
中的宏的一个(较弱的)替代方案是将固定宽度类型转换/强制转换为等效或更大的标准类型。
wprintf(L"%lun", 0ul + some_uint32_t_value);
// or
wprintf(L"%lun", (unsigned long) some_uint32_t_value);