我成功编译了以下代码:
#include <io.h>
#include <fcntl.h>
#include <iostream>
#include <cstddef>
#include <cstdio>
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
char16_t chinese[] = u"\u4e66\u4e2d\u81ea\u6709\u9ec4\u91d1\u5c4b";
wprintf(L"String written with unicode codes: %ls \n", chinese);
wchar_t arabic[] = L"أَبْجَدِيَّة عَرَبِيَّة";
wprintf(L"String written with L-String: %ls \n", arabic);
std::wcout << std::endl; std::system("PAUSE");
}
它打印:
- 用unicode编码编写的字符串:书籍自有黄金屋
- 用 L 字符串编写的字符串: َََََِِّْ ََََِّÉ
但是,编译器会针对中文大小写发出警告(不适用于阿拉伯语大小写):
warning C4477: 'wprintf' : format string '%ls' requires an argument of type 'wchar_t *', but variadic argument 1 has type 'char16_t *'
正确的 wprintf 格式字符串是什么?
最佳答案
wchar_t
与 char16_t
不同。 wchar_t
在 Windows 上是 2 字节字符,但在 Linux 上(通常)是 4 字节字符。这就像 int
与 int16_t
问题一样。该标准未定义 wchar_t
。
所以问题不在于 wprintf 使用什么格式说明符。而是如何将 char16_t
字符串转换为 wchar_t
字符串。
在 Windows 下,您可能只需将 char16_t
转换为 wchar_t
,这就是 wprintf
隐式发生的情况,因为它确实实际上并没有验证它的参数。警告 C4477
只是(Visual Studio?)编译器对您的问题的一点帮助。
但在其他平台上,您必须实际转换字符串。
所以最好的解决方案是这样的:
wprintf("%ls", boost::utf16_to_wchar_t(chinese));
(我只是在这里添加 boost,因为它们有转换函数。我不知道要使用的确切函数)。
或者使用 wchar_t
转义序列并将您的 chinese
定义为 wchar_t*
字符串。
关于用于打印 unicode 字符串的 char16_t 的 C++ wprintf 格式说明符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71006057/