如何在 Visual Studio 2013 中将 stdint 类型与 _tprintf 一起使用? [英] How to use stdint types with _tprintf in Visual Studio 2013?

查看:34
本文介绍了如何在 Visual Studio 2013 中将 stdint 类型与 _tprintf 一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

举个例子:

char* fileName = "C:\\windows\\system32\\kernel32.dll";
uint32_t fileSize = 1163264;
printf("The size of %s is %"PRIu32"\n", fileName, fileSize);

一切都很好,现在如果我们想要通过 tchar.h 透明的 unicode 支持,代码看起来像这样:

Everything is fine, now if we want transparent unicode support via tchar.h the code would look like this:

TCHAR* fileName = _T("C:\\windows\\system32\\kernel32.dll");
uint32_t fileSize = 1163264;
_tprintf(_T("The size of %s is %")_T(PRIu32)_T("\n"), fileName, fileSize);

如果 unicode 定义,则此方法有效.但是,如果定义了 unicode,编译器将中止并显示以下错误:

This works if unicode is not defined. However, if unicode is defined the compiler aborts with the following error:

error C2308: concatenating mismatched strings
Concatenating wide "The size of %s is %l" with narrow "u"

现在看看微软的 inttypes.h 我明白了:

Now looking at Microsoft's inttypes.h I see:

...
#define _PFX_32  "l"
...
#define PRIu32       _PFX_32 "u"

这意味着上面例子中的 _T(PRIu32) 解析为:

Which means that the _T(PRIu32) in the above example resolves to:

_T("l" "u")

...当然不能工作并解释正确的编译器错误.

... which cannot work of course and explains the correct compiler error.

因此我的问题是 Microsoft 是如何想象我们将他们的 inttypes.h 定义与 _tprintf 一起使用的?

Thus my question is how did Microsoft imagine that we use their inttypes.h defines with _tprintf ?

推荐答案

根据当前的 C 标准1,只有一个字符序列(读作:字符串)必须以 a 为前缀一个编码前缀,其余的都被视为具有相同的前缀,并连接成一个字符串.

According1 to the current C standard, only one of the character sequences (read as: a string) must be prefixed by a an encoding prefix, and the rest of them are treated to have the same prefix, and are concatenated into a single string.

编码前缀由_T宏决定.如果未定义 UNICODE,它将解析为空,否则它将在参数前面加上 L.

The encoding prefix is determined by the _T macro. It will resolve to nothing, if UNICODE is not defined, otherwise it will prepend L to the argument.

解决方案是在第一个字符串上使用 _T 宏,其余不使用宏,它们将使用相同的编码:

The solution would be to use the _T macro on the first string, no macro on the rest, and they will use the same encoding:

_tprintf(_T("The size of %s is %") PRIu32 "\n", fileName, fileSize);

但是您使用的 Visual Studio 版本不符合 C99,因此缺少此功能.这似乎已在 Visual Studio 2015 中修复.

But the Visual Studio version you're using isn't C99 compliant, so this feature is missing. It seems this was fixed in Visual Studio 2015.

在标准中的示例2中演示了相同的用法.

The same usage is demonstrated in the example2 in the standard.

1(引用自:ISO/IEC 9899:201x 6.4.5 字符串文字 5)
在翻译阶段 6 中,由任意序列指定的多字节字符序列相邻字符和相同前缀的字符串文字标记连接成一个单个多字节字符序列.如果任何令牌具有编码前缀,则生成的多字节字符序列被视为具有相同的前缀;否则,它被视为字符串文字.是否具有不同前缀的宽字符串文字令牌可以连接,如果是这样,结果多字节字符的处理序列是实现定义的.

1 (Quoted from: ISO/IEC 9899:201x 6.4.5 String literals 5)
In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and identically-prefixed string literal tokens are concatenated into a single multibyte character sequence. If any of the tokens has an encoding prefix, the resulting multibyte character sequence is treated as having the same prefix; otherwise, it is treated as a character string literal. Whether differently-prefixed wide string literal tokens can be concatenated and, if so, the treatment of the resulting multibyte character sequence are implementation-defined.

2(引用自:ISO/IEC 9899:201x 7.8.1 格式说明符 7 的宏)
wprintf(L"最大整数值为%020" PRIxMAX "\n", i);

2 (Quoted from: ISO/IEC 9899:201x 7.8.1 Macros for format specifiers 7)
wprintf(L"The largest integer value is %020" PRIxMAX "\n", i);

这篇关于如何在 Visual Studio 2013 中将 stdint 类型与 _tprintf 一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆