我知道有很多关于转换的信息QString
to char*
,但我仍然需要对这个问题进行一些澄清。
Qt提供QTextCodec
s 要转换QString
(内部以 unicode 形式存储字符)QByteArray
,允许我检索char*
它表示某种非 unicode 编码的字符串。但是当我想要获得unicode时我该怎么办QByteArray
?
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QString qstr = codec->toUnicode("Юникод");
std::string stdstr(reinterpret_cast<const char*>(qstr.constData()), qstr.size() * 2 ); // * 2 since unicode character is twice longer than char
qDebug() << QString(reinterpret_cast<const QChar*>(stdstr.c_str()), stdstr.size() / 2); // same
上面的代码按照我的预期打印“Юникод”。但我想知道这是否是获取 unicode 的正确方法char*
of the QString
。尤其,reinterpret_cast
这种技术中的 s 和大小算术看起来相当难看。
以下内容适用于 Qt 5。Qt 4 的行为有所不同,并且实际上已被破坏。
您需要选择:
是否需要8位宽std::string
或 16 位宽std::wstring
,或其他类型。
您的目标字符串需要什么编码?
在内部,QString
存储 UTF-16 编码数据,因此任何 Unicode 代码点都可以用一个或两个表示QChar
s.
常见案例:
-
本地编码 8 位std::string
(如:系统区域设置):
std::string(str.toLocal8Bit().constData())
-
UTF-8编码8位std::string
:
str.toStdString()
这相当于:
std::string(str.toUtf8().constData())
-
UTF-16 或 UCS-4 编码std::wstring
,分别为 16 位或 32 位宽。 16 位与 32 位编码的选择由 Qt 完成,以匹配平台的宽度wchar_t
.
str.toStdWString()
-
C++11 的 U16 或 U32 字符串 - 从 Qt 5.5 开始:
str.toStdU16String()
str.toStdU32String()
-
UTF-16 编码 16 位std::u16string
- 此 hack 仅在 Qt 5.4 之前需要:
std::u16string(reinterpret_cast<const char16_t*>(str.constData()))
此编码不包括字节顺序标记 (BOM)。
很容易将 BOM 添加到QString
转换之前本身:
QString src = ...;
src.prepend(QChar::ByteOrderMark);
#if QT_VERSION < QT_VERSION_CHECK(5,5,0)
auto dst = std::u16string{reinterpret_cast<const char16_t*>(src.constData()),
src.size()};
#else
auto dst = src.toStdU16String();
如果您预计字符串很大,则可以跳过一份副本:
const QString src = ...;
std::u16string dst;
dst.reserve(src.size() + 2); // BOM + termination
dst.append(char16_t(QChar::ByteOrderMark));
dst.append(reinterpret_cast<const char16_t*>(src.constData()),
src.size()+1);
在这两种情况下,dst
现在可以移植到具有任一字节顺序的系统。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)