【发布时间】:2019-11-21 05:35:50
【问题描述】:
我有一个 UTF-8 编码的文本文件,其中包含 ²、³、Ç 和 ó 等字符。当我使用以下内容读取文件时,文件似乎被正确读取(至少根据我在查看 contents 变量的内容时在 Visual Studio 的编辑器中看到的内容)
QFile file( filePath );
if ( !file.open( QFile::ReadOnly | QFile::Text ) ) {
return;
}
QString contents;
QTextStream stream( &file );
contents.append( stream.readAll() );
file.close();
但是,一旦内容转换为std::string,就会添加其他字符。例如,² 被转换为 ²,而它应该只是 ²。这似乎发生在每个非 ANSI 字符上,添加了额外的 Â,这当然意味着当保存新文件时,输出文件中的字符不正确。
当然,我尝试过简单地使用toStdString(),我也尝试过toUtf8,甚至尝试过使用QTextCodec,但都没有给出正确的值。
我不明白为什么从 UTF-8 文件到 QString,然后到 std::string 会丢失 UTF-8 字符。它应该能够重现最初读取的确切文件,还是我完全遗漏了什么?
【问题讨论】:
-
字符串本身中的多余字符吗?您是否使用调试器检查过?或者您是否仅在打印时看到它(在这种情况下,可能是有缺陷的打印,代码或设置的语言环境或您打印到的终端)。简而言之,您能告诉我们您是如何检查字符串的内容的吗?
-
当使用 QString 的 TextVisualizer 时,我看到
²(如预期的那样),当查看 std::string 的 TextVisualizer 时(在调用 toStdString 之后立即)我看到²,所以它是在文件被写入之前。我还可以在 ANSI(显示上述字符)的 Notepad++ 和 UTF-8 中查看文件(之前和之后),原始文件显示²,新文件显示²。看起来有点像 UTF-8 版本正在展示 ANSI 应该是什么。 -
在谈论字符编码时请不要使用 ANSI,因为没有使用该名称的编码。这只是 Windows 用来表示“根据当前区域设置的代码页”的误称,这导致“ANSI”文本文件几乎总是不能跨不同语言版本的 Windows 移植。
-
顺便说一句。请发布您正在处理的数据的实际十六进制转储,以及它们在通过
QString和std::string后的样子。此外,QTextStream似乎默认准备处理 UTF-16,除非出现 BOM:您是否尝试将文件读取到QByteArray并使用QString::fromUtf8?这还具有额外的优势,即明确说明您在字符编码方面所做的事情。