用于打印 unicode 字符串的 char16_t 的 C++ wprintf 格式说明符

标签 c++ printf

我成功编译了以下代码:

#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_tchar16_t 不同。 wchar_t 在 Windows 上是 2 字节字符,但在 Linux 上(通常)是 4 字节字符。这就像 intint16_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/

相关文章:

c++ - 传递多个变量的最佳实践

集合或数组的 Java printf 功能

c - 如何在 Ubuntu 中修改 glibc 来改变 printf() 函数的结果

c++ - I/O 流操纵器 - 内部调整域 - C++ 与 C

c++ - 如何计算存储在 map 中的 vector 中的元素数量

c++ - 使用front()方法使队列数据结构应用崩溃

c++ - 同一解决方案中不同项目之间的引用(Visual Studio 2012)

c++ - C/C++ 金融库

c - snprintf 在函数内导致中止陷阱 6 但不在 main 中

c - 如何转义 C 的 printf 中的 %(百分号)符号