我知道有很多关于将QString
转换为char*
的信息,但我仍需要在这个问题上做一些澄清。
Qt提供QTextCodec
来将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
上面的代码按照我的预期打印“Юникод”。但是我想知道这是否是到达char*
的unicode QString
的正确方法。特别是,reinterpret_cast
和这种技术中的大小算术看起来非常难看。
答案 0 :(得分:5)
以下内容适用于Qt 5. Qt 4的行为有所不同,实际上已被打破。
您需要选择:
您是想要8位宽std::string
还是16位宽std::wstring
,还是其他类型。
目标字符串中需要什么编码?
在内部,QString
存储UTF-16编码数据,因此任何Unicode代码点都可以用一个或两个QChar
来表示。
常见情况:
本地编码的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位宽。 Qt完成16位与32位编码的选择,以匹配平台宽度wchar_t
。
str.toStdWString()
U ++或U32 C ++ 11字符串 - 从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
现在都可以移植到具有任何字节序的系统。
答案 1 :(得分:2)
使用此:
QString Widen(const std::string &stdStr)
{
return QString::fromUtf8(stdStr.data(), stdStr.size());
}
std::string Narrow(const QString &qtStr)
{
QByteArray utf8 = qtStr.toUtf8();
return std::string(utf8.data(), utf8.size());
}
在所有情况下,你在std :: string中should have utf8。
答案 2 :(得分:0)
您可以使用以下方法从UTF-16编码的QString中获取QByteArray:
QTextCodec *codec = QTextCodec::codecForName("UTF-16");
QTextEncoder *encoderWithoutBom = codec->makeEncoder( QTextCodec::IgnoreHeader );
QByteArray array = encoderWithoutBom->fromUnicode( str );
这样就可以忽略开头的unicode字节顺序标记(BOM)。
您可以将其转换为char *,如:
int dataSize=array.size();
char * data= new char[dataSize];
for(int i=0;i<dataSize;i++)
{
data[i]=array[i];
}
或者简单地说:
char *data = array.data();