восстановить строки выполнения Unicode - PullRequest
1 голос
/ 18 ноября 2011

Я создаю приложение, которое получает строки времени выполнения с закодированным юникодом через tcp, примером строки будет "\ u7cfb \ u8eca \ u4e21 \ uff1a \ u6771 \ u5317 ...".У меня есть следующее, но, к сожалению, я могу извлечь из него пользу только во время компиляции из-за: неполного имени универсального символа \ u, так как во время компиляции ожидается 4 шестнадцатеричных символа.

QString restoreUnicode(QString strText)
   {
      QRegExp rx("\\\\u([0-9a-z]){4}");
      return strText.replace(rx, QString::fromUtf8("\u\\1"));
   }

Я ищу решение вво время выполнения я мог бы предвидеть разбить эти строки и сделать некоторые манипуляции, чтобы преобразовать эти шестнадцатеричные числа после разделителей "\ u" в основание 10, а затем передать их в конструктор QChar, но я ищу лучший способ, если таковой существуетпоскольку меня очень беспокоит сложность времени, вызванная таким методом, я не эксперт.

У кого-нибудь есть какие-либо решения или советы.

Ответы [ 3 ]

1 голос
/ 18 ноября 2011
#include <assert.h>
#include <iostream>
#include <string>
#include <sstream>
#include <locale>
#include <codecvt>          // C++11
using namespace std;

int main()
{
    char const  data[]  = "\\u7cfb\\u8eca\\u4e21\\uff1a\\u6771\\u5317";

    istringstream   stream( data );

    wstring     ws;
    int         code;
    char        slashCh, uCh;
    while( stream >> slashCh >> uCh >> hex >> code )
    {
        assert( slashCh == '\\' && uCh == 'u' );
        ws += wchar_t( code );
    }

    cout << "Unicode code points:" << endl;
    for( auto it = ws.begin();  it != ws.end();  ++it )
    {
        cout << hex << 0 + *it << endl;
    }
    cout << endl;

    // The following is C++11 specific.
    cout << "UTF-8 encoding:" << endl;
    wstring_convert< codecvt_utf8< wchar_t > >  converter;
    string const bytes = converter.to_bytes( ws );
    for( auto it = bytes.begin();  it != bytes.end();  ++it )
    {
        cout << hex << 0 + (unsigned char)*it << ' ';
    }
    cout << endl;
}
1 голос
/ 19 ноября 2011

Для закрытия и всех, кто столкнется с этой веткой в ​​будущем, вот мое первоначальное решение, прежде чем оптимизировать область действия этих переменных. Не фанат этого, но он работает, учитывая непредсказуемую природу unicode и / или ascii в потоке, который я не могу контролировать (только для клиента), в то время как присутствие Unicode низкое, хорошо справиться с этим вместо уродливого \ u1234 и т.д.

QString restoreUnicode(QString strText)
{
    QRegExp rxUnicode("\\\\u([0-9a-z]){4}");

    bool bSuccessFlag;
    int iSafetyOffset = 0;
    int iNeedle = strText.indexOf(rxUnicode, iSafetyOffset);

    while (iNeedle != -1)
    {
        QChar cCodePoint(strText.mid(iNeedle + 2, 4).toInt(&bSuccessFlag, 16));

        if ( bSuccessFlag )
            strText = strText.replace(strText.mid(iNeedle, 6), QString(cCodePoint));
        else
            iSafetyOffset = iNeedle + 1; // hop over non code point to avoid lock

        iNeedle = strText.indexOf(rxUnicode, iSafetyOffset);
    }

    return strText;
}
1 голос
/ 18 ноября 2011

Вы должны декодировать строку самостоятельно.Просто возьмите запись Unicode (rx.indexIn(strText)), проанализируйте ее (int result; std::istringstream iss(s); if (!(iss>>std::hex>>result).fail()) ...) и замените исходную строку \\uXXXX на (wchar_t)result.

...