我有一个连接到IRC服务器的套接字。我想将收到的数据(QByteArray)转换为QString。因为在IRC上,不是每个人都使用UTF-8,我想尝试使用UTF-8解码QByteArray:
QString s = QString::fromUtf8(array);
问题是Qt默默地替换了#34;坏"字符并始终返回QString。我想"尝试"解码,如果它无法正确解码,则回退到latin-1解码。
我怎么能这样做?
答案 0 :(得分:4)
不幸的是,它看起来不像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,{{3}}可能未包含在您使用的Qt版本中。据推测,他们最终还会添加fromStdU16String()
之类的内容,以便您可以说QString::fromStdU16String(s16)
,或者添加隐式转化,这样您就可以说s = s16;
。
另请注意,libstdc ++(gcc的默认标准库实现)尚未包含此转换工具。 Visual Studio 2010及更高版本拥有它,而libc ++拥有它。