读/写/打印C+格式的UTF-8+;11

读/写/打印C+格式的UTF-8+;11,utf-8,c++11,wchar-t,utf-32,codecvt,Utf 8,C++11,Wchar T,Utf 32,Codecvt,我一直在探索C++11的新Unicode功能,虽然非常有帮助,但我对下面的代码片段有一个问题。代码写入并立即读取使用UTF-8编码保存的文本文件 // 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

我一直在探索C++11的新Unicode功能,虽然非常有帮助,但我对下面的代码片段有一个问题。代码写入并立即读取使用UTF-8编码保存的文本文件

// 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';
//写
std::ofstream(“text.txt”)c;)/?

std::cout您使用的cppreference代码片段的思想是展示如何将UTF-8文件读入UTF-16字符串,这就是为什么他们使用ofstream编写文件,但使用wifstream(因此是wchar_t)读取文件。

您使用
wchar_t
是因为您使用
wifstream
读取文件;如果您使用
ifstream
阅读,您将使用
char
,对于
char16\u t
char32\u t
也是如此


假设(如示例所示)
wchar\u t
是32位的,并且它表示的本机字符集是UTF-32(UCS-4),那么这是将文件读取为UTF-32的最简单方法;在本例中如此呈现是为了与将文件读取为UTF-16形成对比。一种更方便的方法是显式地使用
basic\u ifstream
std::codevt\u utf8
,因为这保证了从UTF-8输入流转换为UTF-32元素。

这取决于很多因素。值得注意的是,如果在控制台应用程序中使用Windows(至少需要大量非标准API调用IIRC),那么正确的UTF8行为是极其困难的,因为使用了
wifstream
,并且
wifstream
执行您提到的“一些自动转换”。我的意思是要说明自动转换(在一个特定平台上实现)与
codevt\u utf8\u utf16
+1提供的显式、可移植、独立于语言环境的Unicode转换之间的区别,我写了这个例子,对比就是我想要的。啊,我明白了!因此,始终将UTF-8显式转换为更宽的
wchar\u t
是更好的做法,还是仍然可以使用
ifstream
将原始UTF-8字节提取到本机
char
数组中?我不确定是否要从@Cubbi的示例中推断后者是不好的做法,或者它是否超出了示例的范围。@PLPiper是的,您始终可以将文件中的任何多字节编码读入字符数组,而无需进行任何转换。用标准C++中的数组(除了转换为第一个)之外,没有很多可以做的事情,但是大量的库使用UTF8输入。