Qt QString到unicode标准::字符串

Qt QString到unicode标准::字符串,qt,unicode,encoding,qstring,Qt,Unicode,Encoding,Qstring,我知道有很多关于将QString转换为char*的信息,但在这个问题上我仍然需要一些澄清 Qt提供了QTextCodecs来将QString(内部以unicode格式存储字符)转换为QByteArray,允许我检索char*,它以一些非unicode编码表示字符串。但是当我想要一个unicodeQByteArray时,我应该怎么做呢 QTextCodec* codec = QTextCodec::codecForName("UTF-8"); QString qstr = codec->to

我知道有很多关于将
QString
转换为
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
QTextCodec*codec=QTextCodec::codeforname(“UTF-8”);
QString qstr=codec->toUnicode(“ЮЮЮЮЮЮЮЮЮЮЮЮ;
std::string stdstr(重新解释转换(qstr.constData()),qstr.size()*2);//*2因为unicode字符比char长两倍

qDebug()您可以使用以下方法从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];
}

以下内容适用于Qt 5。Qt 4的行为是不同的,实际上是不正常的。

您需要选择:

  • 您想要的是8位宽的
    std::string
    还是16位宽的
    std::wstring
    或其他类型

  • 目标字符串中需要什么编码

  • 在内部,
    QString
    存储UTF-16编码数据,因此任何Unicode码点都可以用一个或两个
    QChar
    s表示

    常见情况:

    • 本地编码的8位
      std::string
      (如:系统区域设置):

    • UTF-8编码的8位
      std::string

      str.toStdString()
      
      这相当于:

      std::string(str.toUtf8().constData())
      
    • UTF-16或UCS-4编码的
      std::wstring
      ,分别为16或32位宽。Qt选择16位与32位编码,以匹配平台的
      wchar\u t
      宽度

      str.toStdWString()
      
    • C++11的U16或U32字符串-从Qt 5.5开始:

      str.toStdU16String()
      str.toStdU32String()
      
    • UTF-16编码的16位
      std::u16string
      -此破解仅在Qt 5.4之前需要:

      std::u16string(reinterpret_cast<const char16_t*>(str.constData()))
      
      如果希望字符串较大,可以跳过一个副本:

      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);
      
      const QString src=。。。;
      std::U16字符串dst;
      dst.reserve(src.size()+2);//BOM+终止
      追加(char16_t(QChar::ByteOrderMark));
      追加(reinterpret_cast(src.constData()),
      src.size()+1);
      
      在这两种情况下,
      dst
      现在可移植到具有任意端的系统。

      使用以下方法:

      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中使用utf8

      @ratchetfreak你是说UTF8和Unicode是相等的吗?UTF8是字节大小的Unicode格式,QString内部使用UTF16,你也可以获取
      data()
      QString已经是“юааа”。因此只需调用
      str.toStdWString()
      std::string
      不是为存储16位字符而设计的。“您的意思是UTF8和Unicode相等”否。您使用Unicode这个词是错误的。Unicode不是一种编码,它是一种标准,所以谈论“Unicode std::string”并没有任何意义。字符串本身不能与unicode兼容。
      std::string
      将具有特定的“字符”类型(通常为8位或16位宽),并具有特定的编码(通常为16位字符的UCS-2或UTF-16)。UCS-2和UTF-16之间的最大区别在于UCS-2的宽度是固定的:每个“字符”有一个代码点。在UTF-16中,每个代码点可能有多个“字符”。短语“unicode QByteArray”没有意义。这相当于说“wakalixes QByteArray”。字节数组可以以某些8位编码(如Latin1(ISO/IEC 8859-1)或UTF-8等)携带文本数据。如果您希望以8位编码的字节数组作为字符串的表示,则需要知道这样一个数组的用户希望使用什么编码。只有这样,你才能决定如何对字符串进行编码。没有“unicode字节数组”这样的东西——请停止使用这个术语,它会让每个人都感到困惑。Unicode是一种标准,而不是编码。有UTF-16和UCS-2,后者是
      QString
      内部编码的内容。UCS-2是代码点0-0xFFFF的UTF-16的子集。由于
      QString
      不能携带超出该范围的代码点,因此无需做任何特殊操作即可将UTF-16移出
      QString
      。只需使用字符串的
      constData()
      @KubaOber Using constData()也可以在乞讨时获得BOM,这是一个混乱。使用上述方法,您可以获得与字符串相关的QByteArray,也可以使用不同的编码选项。您确定
      QString
      存储嵌入的BOM表吗?是的。您可以看到,事实上,我刚刚检查过,
      QString
      没有嵌入BOM。那是浪费空间。此代码将转储BOM;它不是:
      qstringstr1(QStringLiteral(“A”);常量QChar*p=str1.constData();而(p->unicode())qDebug()为什么从UTF8调用时需要
      stdStr.size()
      ?这是否会导致在QString中存储终止null?否则,它将从UTF8显示
      默认为读取到终止null。。。
      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);
      
      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());
      }