Russian Qt Forum

Qt => Работа с сетью => Тема начата: vbi от Апрель 15, 2013, 11:08



Название: Как в ответе QNetworkReply найти кириллический текст?
Отправлено: vbi от Апрель 15, 2013, 11:08
Собственно САБЖ.
Работал с QWebView - проблем не было. QWebView возвращает QString:

Код:
QString data = MyWebView->page()->mainFrame()->toHtml();
Ответ в QString, искомый текст в QString. QString ищу в QString - все норм.

Но мне нужно использовать QNetworkAccessManager, а его ответ, это QNetworkReply, а он возвращает ответ в QByteArray... И тут понеслось... :)

Код:
QByteArray data = reply->read(reply->bytesAvailable());

Теперь у меня есть QByteArray. Нужно в нем найти подстроку QString. Вот собственно задача.

Пробую конвертировать QString в QByteArray - не получается:

Код:
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("CP1251"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("CP1251"));
    QString s = tr("Тест");
    QByteArray b = s.toAscii();
    b = s.toLatin1();
    b = s.toLocal8Bit();
    b = s.toUtf8();

Во всех случаях в "b" оказываются кракозябры, по крайней мере так показывает отладчик в QtCreator 2.4.1. Слышал что отладчик может неправильно просто отображать значение QByteArray. Но при попытке поиска подстроку не находит.

Кстате в data я не знаю какая кодировка HTML страницы:

Код:
QByteArray data = reply->read(reply->bytesAvailable());

Как мне QByteArray data найти подстроку QString?


Название: Re: Как в ответе QNetworkReply найти кириллический текст?
Отправлено: Kurles от Апрель 15, 2013, 11:33
Надо QTextCodec использовать
Код
C++ (Qt)
QTextCodec *codec = QTextCodec::codecForName("CP1251");
QString s = tr("Тест");
QByteArray b = codec->fromUnicode(s);
 
Примерно так

update: кодировку надо вытаскивать из HTML тегов, и в зависимости от этого создавать экземпляр QTextCodec.


Название: Re: Как в ответе QNetworkReply найти кириллический текст?
Отправлено: vbi от Апрель 15, 2013, 12:51
Пробовал и "fromUnicode" - Крейтор все раавно отображает разные кракозябры.

Ну хорошо, тогда QString мне нужно приводить в ту кодировку, в которой будет HTML страница?

Не подскажете класс/функционал который определяет кодировку по тегам. Наверное я не первый пытаюсь это сделать :)


Название: Re: Как в ответе QNetworkReply найти кириллический текст?
Отправлено: RedDog от Апрель 15, 2013, 12:54
Код
HTML
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
Одену строку распарсить можно и руками


Название: Re: Как в ответе QNetworkReply найти кириллический текст?
Отправлено: vbi от Апрель 17, 2013, 17:51
Надо QTextCodec использовать
Код
C++ (Qt)
QTextCodec *codec = QTextCodec::codecForName("CP1251");
QString s = tr("Тест");
QByteArray b = codec->fromUnicode(s);
 
Примерно так

update: кодировку надо вытаскивать из HTML тегов, и в зависимости от этого создавать экземпляр QTextCodec.

Так не получилось. Не находит подстроку. В отладке всеравно подстрока отображается кракозябрами.

Но получилось найти так:
Код:
QByteArray::indexOf(QString) == -1


Название: Re: Как в ответе QNetworkReply найти кириллический текст?
Отправлено: thechicho от Май 02, 2013, 12:05
в main.cpp

    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForLocale(codec);

читаешь ответ
        QString answer;
        if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
            answer = uncompress(reply->readAll());
        } else {
            answer = reply->readAll();
        }

QByteArray Class::uncompress(const QByteArray &data)
{
    if (data.size() <= 4) {
        qWarning("uncompress: Input data is truncated");
        return QByteArray();
    }

    QByteArray result;

    int ret;
    z_stream strm;
    static const int CHUNK_SIZE = 1024;
    char out[CHUNK_SIZE];

    /* allocate inflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = data.size();
    strm.next_in = (Bytef*)(data.data());

    ret = inflateInit2(&strm, 15 +  32); // gzip decoding
    if (ret != Z_OK)
        return QByteArray();

    // run inflate()
    do {
        strm.avail_out = CHUNK_SIZE;
        strm.next_out = (Bytef*)(out);

        ret = inflate(&strm, Z_NO_FLUSH);
        Q_ASSERT(ret != Z_STREAM_ERROR);  // state not clobbered

        switch (ret) {
        case Z_NEED_DICT:
            ret = Z_DATA_ERROR;     // and fall through
        case Z_DATA_ERROR:
        case Z_MEM_ERROR:
            (void)inflateEnd(&strm);
            return QByteArray();
        }

        result.append(out, CHUNK_SIZE - strm.avail_out);
    } while (strm.avail_out == 0);

    // clean up and return
    inflateEnd(&strm);
    return result;
}

чтобы zlib работал в .про
INCLUDEPATH += $$[QT_INSTALL_PREFIX]/src/3rdparty/zlib
ну и инклюдишь #include "zlib.h"

еще кодировку файлов с кодом можешь перевести в UTF-8 и спокойно использовать кириллицу прямо в коде.