0

众所周知,要打印类型为固定宽度整数类型之一(如uint32_t)的变量的值,您需要包含cinttypes(在 C++ 中)或inttypes.h(在 C 中)头文件并使用格式说明符宏,如PRIu32. wprintf但是在使用函数时如何做同样的事情呢?在这种情况下,此类宏应扩展为带有L前缀的字符串文字。

4

4 回答 4

5

这是否有效取决于编译器使用的 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);
于 2016-04-29T13:49:59.050 回答
3

不确定问题出在哪里,但在这里(VS 2015)两者

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

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

正确编译并给出以下输出:

AA 123 BB
于 2016-04-29T14:01:15.940 回答
1

使用宏的(较弱)替代方法<inttypes.h>是将固定宽度类型转换/转换为等效或更大的标准类型。

wprintf(L"%lu\n", 0ul + some_uint32_t_value);
// or 
wprintf(L"%lu\n", (unsigned long) some_uint32_t_value);
于 2016-04-29T14:32:46.513 回答
1

即使您的编译器不支持不同前缀文字的连接,您也可以随时加宽一个狭窄的文字:

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

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

演示

于 2016-04-29T14:18:18.943 回答