不幸的是,Qt 似乎没有提供解码例程来允许配置其处理无效序列。
相反,您应该能够执行以下操作:
QString s = QString::fromUtf8(array);
if (s.toUtf8() != array) {
s = QString::fromLatin1(array);
}
UTF-8 和 UTF-16 之间的直接转换(即无规范化)应该是无损且完全可逆的。如果从 UTF-16 转换为 UTF-8 不会产生原始数据,那是因为原始数据不是有效的 UTF-8。
虽然在正常情况下不太可能,但某些其他编码的文本可能恰好是有效的 UTF-8,但在 UTF-8 与正确的编码中具有不同的含义。这样的文本将被检测为 UTF-8,并且不会按预期显示。避免这种情况的唯一方法是事先了解正确的编码,例如通过正确编码的协议声明。
另一个选择是使用std::wstring_convert,它是 C++11 标准库的一部分。
#include <codecvt> // for codecvt_utf8_utf16
#include <locale> // for wstring_convert
QByteArray array = ...
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
QString s;
try {
std::u16string s16 = converter.from_bytes(array.data(), array.size());
s = QString::fromUtf16(s16.c_str());
} catch(...) {
s = QString::fromLatin1(array);
}
注意fromUtf16 与char16_t 的使用取决于this change,您使用的Qt 版本中可能不包含该this change。据推测,他们最终还会添加类似fromStdU16String() 的内容,因此您可以说QString::fromStdU16String(s16),或者可能添加隐式转换,因此您可以直接说s = s16;。
另请注意,libstdc++(gcc 的默认标准库实现)尚不包含此转换工具。 Visual Studio 2010 及更高版本有,libc++ 有。