char16_t 的 C++ wprintf 格式说明符,用于打印 unicode 字符串
C++ wprintf format specifier for char16_t for printing unicode string
我成功编译了以下代码:
#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*
字符串。
What would be then the correct wprintf format string?
char16_t
没有 printf
格式说明符。它不存在。
您必须将 char16_t
字符串转换为多字节字符串或宽字符串,然后打印它。
c16rtomb
将是执行此操作的标准 C 函数。 Convert between string, u16string & u32string 显示如何在 C++ 中执行此操作。
我成功编译了以下代码:
#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*
字符串。
What would be then the correct wprintf format string?
char16_t
没有 printf
格式说明符。它不存在。
您必须将 char16_t
字符串转换为多字节字符串或宽字符串,然后打印它。
c16rtomb
将是执行此操作的标准 C 函数。 Convert between string, u16string & u32string 显示如何在 C++ 中执行此操作。