在C++中读写/打印UTF-8 11
我一直在探索C++ 11的新Unicode功能,虽然other C++11 encoding questions已经非常有帮助,但我对cppreference以下代码段有疑问。代码写入并立即读取以UTF-8编码保存的文本文件。在C++中读写/打印UTF-8 11
// Write
std::ofstream("text.txt") << u8"z\u6c34\U0001d10b";
// Read
std::wifstream file1("text.txt");
file1.imbue(std::locale("en_US.UTF8"));
std::cout << "Normal read from file (using default UTF-8/UTF-32 codecvt)\n";
for(wchar_t c; file1 >> c;) // ?
std::cout << std::hex << std::showbase << c << '\n';
是很简单的,为什么是wchar_t
需要在for
环路我的问题? A u8
字符串文字可以使用简单的char *
来声明,而UTF-8编码的位布局应该告诉系统字符的宽度。看起来有一些从UTF-8到UTF-32的自动转换(因此wchar_t
),但如果是这种情况,为什么需要转换?
您使用wchar_t
,因为您使用wifstream
来读取文件;如果您正在使用ifstream
进行阅读,则您将使用char
,并且类似地使用char16_t
和char32_t
。
假设(作为示例执行),该wchar_t
是32位,并且所述本地字符集,它代表是UTF-32(UCS-4),那么这是要读取的文件作为最简单的方法UTF-32;它在这个例子中是这样表示的,以便将文件读作UTF-16。更为便携的方法是明确使用basic_ifstream<char32_t>
和std::codecvt_utf8<char32_t>
,因为这可以保证从UTF-8输入流转换为UTF-32元素。
+1,我写这个例子和对比是我的目标。 – Cubbi 2013-03-18 13:54:02
啊我明白了!因此,总是明确地将UTF-8转换为更宽的'wchar_t',或者使用'ifstream'将原始UTF-8字节提取到本地'char'数组中是否可以接受?我不确定是否从@ Cubbi的例子推断后者是不好的做法,或者它是否超出了范例的范围。 – Ephemera 2013-03-19 00:47:40
@PLPiper是的,你可以随时读取任何多字节编码文件到char数组中,而无需进行任何转换。使用标准C++中的这样的数组没有太多的功能(除了首先转换为宽),但是大量的库需要使用utf8输入。 – Cubbi 2013-03-19 02:26:00
您使用的cppreference代码片段的想法是展示如何将UTF-8文件读取到UTF-16字符串中,这就是为什么他们使用ofstream编写文件,但是使用wifstream读取文件(因此wchar_t) 。
这取决于很多事情。值得注意的是,正确的UTF8行为在控制台应用程序中使用Windows时不是不可能的(如果不是不可能的话)(要求_至少有很多非标准API调用IIRC) – sehe 2013-03-18 10:57:10
使用'wchar_t'是因为使用了wifstream而wifstream执行你提到的“一些自动转换”。我的观点是要展示自动转换(为一个特定平台实现)和'codecvt_utf8_utf16'提供的明确的,可移植的,与区域无关的Unicode转换之间的区别。 – Cubbi 2013-03-18 14:29:33