Russian Qt Forum
Ноябрь 28, 2024, 10:15 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Преобразование из QDataStream русского текста  (Прочитано 8963 раз)
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« : Август 19, 2016, 13:16 »

Здравствуйте
Мне надо преобразовать русский текст из QDataStream.
В реальной задаче я по сети передаю через QDataStream.
В тестовом примере во вложении я беру строки на английском и на русском, кодирую их через QDataStream, а затем пробую раскодировать с помощью QTextDecoder, получившееся вывожу в QLabel.
Можете подсказать как правильно декодировать? Что я делаю не так?
Это основной текст примера:
    QString s1("Русский");                                                                              //строка на русском языке
    QTextDecoder *decoder = QTextCodec::codecForName("UTF-8")->makeDecoder(QTextCodec::IgnoreHeader);   //Декодер из UTF8
    QString s2("Russian");                                                                              //строка на английском языке
    QByteArray ba;                                                                                      //QByteArray, в который идет кодирование с помощью QDataStream
    QDataStream ds(&ba,QIODevice::ReadWrite);
    ds << s2;                                                                                           //"помещение" строки на англ. в QDataStream
    s2.clear();                                                                                         //очищение строки (для чистоты эксперимента)
    s2 = decoder->toUnicode(ba);                                                                         //декодирование
    ui->label->setText(s2);                                                                              //установка в QLabel, раскодировалось в целом нормально
    ba.clear();                                                                                         //очищение QByteArray (для чистоты эксперимента)
    //тоже самое для строки с русским текстом
    ds << s1;
    s1.clear();
    s1 = decoder->toUnicode(ba);
    ui->label_2->clear();
    ui->label_2->setText(s1);
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Август 19, 2016, 14:26 »

Сам принцип работы неверный.

Для сохранения и восстановления QString в QDataStream никакой кодировщик не нужен.

Код:
QString s1("Русский");
QByteArray ba;
QDataStream out_stream( &ba,QIODevice::WriteOnly );
out_stream << s1;

s1.clear();
QDataStream in_stream( &ba,QIODevice::ReadOnly );
in_stream >> s1;

Если хотите пользоваться кодировщиком, то не нужен QDataStream

Код:
QString s1("Русский");
QByteArray ba = decoder->fromUnicode( s1 );
...
s1.clear();
s1 = decoder->toUnicode( ba );

Нет никакой гарантии, что сериализация/десмериализация QString посредством QDataStream как-то равнозначно кодированию/декодированию. Скорее наоборот - гарантировано, что они не равнозначны.
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #2 : Август 22, 2016, 13:54 »

Спасибо, это правильно.
Кодировка у меня портится, когда я с помощью QDataStream пересылаю из QNX в Windows. Из Windows в Windows работает, из Windows в QNX тоже, а из QNX в Windows и из QNX в QNX не работает. QNX 6, QT 4.8.
В вложении что-то типа клиент-серверного приложения. Сервер и клиент обмениваются QList<QStringList>. Сервер запускается сначала=))
Не знаете, в чем может быть проблема и какие варианты ее исправить?
Записан
Bepec
Гость
« Ответ #3 : Август 22, 2016, 14:26 »

Вы код покажите. А там мб и разберёмся Веселый
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #4 : Август 22, 2016, 14:40 »

Простите, про вложения забыл
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #5 : Август 23, 2016, 12:40 »

Проблемы приблизительно следующего плана:
Если я передаю слово "Лед" с сервера, то на на клиенте у меня появляются следующие кракозябры: ╨Ы╨╡╨┤. Если вставить их в онлайн-декодер Лебедева, то получим нужное слово "Лед".
Там написано, что было сделано преобразование CP866 → UTF-8
https://www.artlebedev.ru/tools/decoder/ - декодер Лебедева
Вывожу так:
void MainWindow::M_writeLabel(QByteArray string)
{
    QString s;
    QDataStream ds(&string,QIODevice::ReadOnly);
    ds >> s;
    ui->label->setText(s);
}
Можете подсказать, что сделать, чтобы в QLabel вместо кракозябр выводилось слово "Лед"
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Август 23, 2016, 12:57 »

Покажите как формируются данные с строкой на стороне сервера.
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #7 : Август 23, 2016, 13:04 »

QByteArray socketArray;
QString s("Лед");
QDataStream ds1(&socketArray,QIODevice::WriteOnly);
ds1 << s;
socket->write(socketArray);
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Август 23, 2016, 13:35 »

Исходники у вас в UTF-8, поэтому для Qt4 нужно явно использовать преобразование из UTF-8.
Например:
Код
C++ (Qt)
QString s( trUtf8( "Лед" ) );
QString s = QString::fromUtf8( "Лед" );
QString s = QTextCodec::codecForName( "UTF-8" )->toUnicode( "Лед" );
 

Но все это будет работать для исходников в UTF-8. Если кодировка исходников поменяется, нужно будет использовать другой кодек.
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #9 : Август 23, 2016, 13:52 »

Я получаю QString (слово "Лед" в этом формате), который нужно перекодировать. Как его в данном случае лучше преобразовать в QByteArray? Подойдет ли метод toUtf8()?
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Август 23, 2016, 13:53 »

Подойдет ли метод toUtf8()?
Да. Или более универсальное решение с QTextCodec::fromUnicode.
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #11 : Август 23, 2016, 14:05 »

Можете поподробнее, пожалуйста.
Я получаю строку s в кодировке CP866 в QString. Как мне получить эту строку в формате UTF-8?
Как-то так QString s1 = QTextCodec::codecForName("UTF-8)->toUnicode(s.toUtf8())  ?
Это не помогает
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #12 : Август 23, 2016, 14:46 »

Можете поподробнее, пожалуйста.
Я получаю строку s в кодировке CP866 в QString. Как мне получить эту строку в формате UTF-8?
Как-то так QString s1 = QTextCodec::codecForName("UTF-8)->toUnicode(s.toUtf8())  ?
Это не помогает
Нельзя получить строку в кодировке отличной от Unicode. Вы получаете QByteArray со строкой в кодировке CP866, ее вы можете преобразовать в строку QString (она уже будет в Unicode), а затем еее можно преобразовать опять в QByteArray со строкой в кодировке UTF-8.
Т.е. это идет двойное преобразование:
CP866 (QByteArray) -> Unicode (QString) -> UTF-8 (QByteArray)

Все это делается через QTextCodec.
Записан
YvenTitan
Самовар
**
Offline Offline

Сообщений: 174


Просмотр профиля
« Ответ #13 : Август 23, 2016, 15:10 »

Пробую - строка меняет содержание.
А можно как-то из QByteArray или файла, в которых содержатся кракозябры ╨Ы╨╡╨┤получить (вывести) слово "Лед"?
Мне предлагают вообще написать функцию декодирования. Можно как-то без этого обойтись?
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #14 : Август 23, 2016, 15:29 »

Пробую - строка меняет содержание.
А можно как-то из QByteArray или файла, в которых содержатся кракозябры ╨Ы╨╡╨┤получить (вывести) слово "Лед"?
Мне предлагают вообще написать функцию декодирования. Можно как-то без этого обойтись?
Судя по всему это строка "Лед" в UTF-8. Например, она хранится в файле, тогда вы можете прочитать эти данные в QByteArray (QFile::readAll), а затем преобразовать в Unicode^
Код
C++ (Qt)
QByteArray data = file.readAll();
QString text = QTextCodec::codecForName( "UTF-8" )->toUnicode( data );
label->setText( text ); // В text находится строка "Лед" в Unicode.
 
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.113 секунд. Запросов: 23.