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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: При изменении кодировки с 1251 на 866 пропадает буква Ш  (Прочитано 15603 раз)
sibmail
Гость
« : Апрель 20, 2010, 13:42 »

Пример кода
...
QTextCodec *codec=QTextCodec::codecForName("CP1251");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForLocale(codec);
...
...

QTextCodec *codec_send = QTextCodec::codecForName("IBM-866");

QString mes_send="ШИШ;
emit message (mes_send); //выводит "ШИШ"

mes_send=codec_send->fromUnicode(mes_send);

emit message (mes_send); //что то там выводит...

mes_send=codec_send->toUnicode(mes_send);

emit message (mes_send); //выводит "?И?"

подскажите что делать?
Записан
vadim303
Гость
« Ответ #1 : Апрель 20, 2010, 14:47 »

Код:
mes_send=codec_send->fromUnicode(mes_send);
Вы преобразуете строку в байтовый массив содержаций вашу строку в кодировке codec_send и затем оператором = преобразуете этот массив к строке посредством кодека установленного в  QTextCodec::setCodecForCStrings(). Соответственно получаете глупость. Смотрите внимательно неявные преобразования между QByteArray и QString в конструкторах копирования и операторах присваивания. Там везде используется кодек QTextCodec::codecForCStrings().
Записан
sibmail
Гость
« Ответ #2 : Апрель 21, 2010, 04:24 »

так как конкретно преобразовать?
все буквы нормально работают кроме Ш
Записан
vadim303
Гость
« Ответ #3 : Апрель 21, 2010, 09:15 »

Не совсем понятно чего вы хотите добиться... По любому QString будет хранить строки в юникоде, какую бы кодировку на вход вы не дали. Главное правильный кодек для преобразования всучить, чтобы не получить внутри глупость. Если же вы хотите к примеру из кодировки cp1251 получить ibm-866 (а это однобайтовые кодировки), то можно с помощью кодека 1251 загонять символьный массив (тот же "ШИШ") в QString, а потом с помощью кодека 866 получать массив в QByteArray, и с помощью метода data() уже получать символьный массив в искомой кодировке.

Примерно так:

Код:
char* str1 = "ШИШ"; // исходник должен быть набран в cp1251
QString buf = QTextCodec::codecForName("CP1251")->toUnicode(str1);
char *str2 = new char[buf.size()];
strcpy(str2, QTextCodec::codecForName("IBM-866")->fromUnicode(buf).data());// теперь в str2 содержится ШИШ в кодировке IBM-866
« Последнее редактирование: Апрель 21, 2010, 09:34 от vadim303 » Записан
sibmail
Гость
« Ответ #4 : Апрель 21, 2010, 11:41 »

Qt3.3.8
to vadim303 - Не получается...
Детально: в программе формируются строки для посылки, строка состоит из ранзых блоков (в зависимости от протокола).
Я не могу перекодировать все данные перед отправкой, т.к. в служебной части строки есть данные которые нельзя менять.
...
QTextCodec *codec=QTextCodec::codecForName("CP1251");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForLocale(codec);
...
...
QString mes_send1="12345;
QString mes_send2="ШИШ2;
QString mes_send3="ШИШ3;

QTextCodec *codec_send = QTextCodec::codecForName("IBM-866");

mes_send2=codec_send->fromUnicode(mes_send2);
mes_send3=codec_send->fromUnicode(mes_send3);

QString array_Strings[n_devices][1];

array_Strings[0][0]=mes_send2;
array_Strings[1][0]=mes_send3;

QString MES_SEND=mes_send1+array_Strings[0][0]+array_Strings[1][0];  //часть строки должна быть в IBM-866

m_psocket->writeBlock(MES_SEND, MES_SEND.length());
« Последнее редактирование: Апрель 21, 2010, 11:44 от sibmail » Записан
vadim303
Гость
« Ответ #5 : Апрель 21, 2010, 12:18 »

Блин, опять за старое:
Код:
mes_send2=codec_send->fromUnicode(mes_send2);
codec_send возвращает QByteArray. Я так понимаю ваш ШИШ записанный в исходнике в кодировке 1251 вы преобразуете в 866-ю. Но дальше то опять присваиваете этот QByteArray к QString, а оператор присваивания вызывает преобразование кодеком заданным в QTextCodec::setCodecForCStrings, (кодеком преобразования в 1251). Т.е. вы строку с кодировке 866 преобразуете зачем-то в юникод кодеком для кодеровки 1251 и при этом хотите чтобы получилось что-то осмысленное?
Записан
sibmail
Гость
« Ответ #6 : Апрель 21, 2010, 12:21 »

я понимаю это, так что делать то теперь?

ситуация такая что надо иметь строку состоящую из разных кодировок, причем в БД надо записать в 1251, а отправить в 866
Записан
vadim303
Гость
« Ответ #7 : Апрель 21, 2010, 12:29 »

Если вот здесь:
Код:
m_psocket->writeBlock(MES_SEND, MES_SEND.length());
вам надо передать что-то в кодировке 866, то туда не юникод надо передавать (MES_SEND это QString, а QString всегда содержит юникод), а символьный массив (char*) или QByteArray содержащий результат codec_send->fromUnicode(ваш QString); Если строка из разных кодировок, то лучше оперировать QByteArray. Т.е. преобразуете ваши QString-и в нужные кодировки и результаты (ни в коем случае не преобразуя их в QString) складываете к примеру тем же самым оператором сложения. Т.е. как я писал предыдущим постом, ваша главная ошибка в присвоении результатов преобразования обратно в QString.
Записан
SABROG
Гость
« Ответ #8 : Апрель 21, 2010, 14:19 »

ситуация такая что надо иметь строку состоящую из разных кодировок, причем в БД надо записать в 1251, а отправить в 866
С этого и надо было начинать. Я так понимаю клиент берет строку в 1251, переводит в 866 для передачи по сокету, сервер берет строку в 866 и перекодирует снова в 1251, а потом её кладет в базу? Или все-таки пакет может быть такого формата:

"Добавить в базу данных строку (cp866): 'ШИШ' (cp1251)" ?

Тогда определенно QByteArray или const char массив. Для сравнения:

Код:
QString str1("ШИШ"); // строка будет в Unicode кодировке (2 байта на символ) при правильно заданном кодеке
QByteArray str1("ШИШ"); // строка будет в кодировке исходника (1251 например) (1 байт на символ).
QLatin1String str2("ABC"); // строка будет в ASCII/Latin1 (1 байт на символ)
QString str3(QLatin1String("ABC")); строка будет в Unicode кодировке (преобразование latin1/ASCII (8 бит) в Unicode (16 бит)).

Код:
QLatin1String("Test"): длина 4 байта 0x54 0x65 0x73 0x74
QString(QLatin1String("Test")): длина 8 байт 0x00 0x54 0x00 0x65 0x00 0x73 0x00 0x74
QByteArray("Test"): длина 4 байта 0x54 0x65 0x73 0x74
QString(QByteArray("Test")): длина 8 байт 0x00 0x54 0x00 0x65 0x00 0x73 0x00 0x74

Ну и соответственно QString(QByteArray()) равносильно присваиванию QString = QByteArray.
Записан
sibmail
Гость
« Ответ #9 : Апрель 21, 2010, 14:28 »

лучше бы создатели кодировок сразу с буквой Ш вопрос решили...

http://www.getinfo.ru/article296_1.html
Что же произошло? Куда делась буква Ш? Весь фокус здесь в том, что произошла взаимокомпенсация двух ошибок. Текстовый редактор в Far по умолчанию создаёт файл в DOS-кодировке (Cp866). Компилятор же javac для чтения исходника использует file.encoding (если не указано иное ключиком -encoding). А в среде Windows с русскими региональными настройками кодировкой по умолчанию является Cp1251. Это первая ошибка. В результате, в скомпилированном файле Test.class символы имеют неверные кода. Вторая ошибка состоит в том, что для вывода используется стандартный PrintStream, который тоже использует настройку из file.encoding, однако консольное окно в Windows отображает символы, используя кодировку DOS. Если бы кодировка Cp1251 была взаимоодназначной, то потери данных бы не было. Но символ Ш в Cp866 имеет код 152, который в Cp1251 не определён, и поэтому отображается на Unicode-символ 0xFFFD. Когда происходит обратное преобразование из char в byte, вместо него подставляется символ '?'.

подскажите как правильно сложить QByteArray
делаю так, но проблема:

QString str1="ШИШ";
QByteArray ba1, ba2;

ba1="12345"+QCString(str1);
ba2="67890";
ba1=ba1+ba2; // - вот типа такой сюжет как правильно сложить???
Записан
vadim303
Гость
« Ответ #10 : Апрель 21, 2010, 14:39 »

Буква Ш теряется в данном случае потому что у вас данные в кодировке 866 передаются кодеку 1251 и он неверно их интерпретирует.

Далее: в принципе мысль со сложением верна, но внимательно будьте с присвоением QString в QByteArray - в операторе присваивания вызывается перекодировщик и он опять может быть не тем что вам нужен. При преобразовании из QString в QByteArray лучше явно вызывать fromUnicode соответствующего кодека, раз у вас такой набор разных кодировок используется.
Записан
sibmail
Гость
« Ответ #11 : Апрель 21, 2010, 15:55 »

у меня qt3. там много чего нет...

подскажите как правильно сложить QByteArray
делаю так, но проблема:

QString str1="ШИШ";
QByteArray ba1, ba2;

ba1="12345"+QCString(str1);
ba2="67890";
ba1=ba1+ba2; // - вот типа такой сюжет как правильно сложить???
Записан
vadim303
Гость
« Ответ #12 : Апрель 21, 2010, 16:00 »

Ничё не понял... в qt3 нет оператора сложения QByteArray? Что значит как правильно сложить? Напишите какие строки и в каких кодировках имеются и в каких кодировках вы хотите их сложить.
Записан
sibmail
Гость
« Ответ #13 : Апрель 21, 2010, 16:22 »

QString str1="ШИШ";
QByteArray ba1, ba2;

ba1="12345"+QCString(str1);
ba2="67890";
ba1=ba1+ba2; // - ВОТ ЗДЕСЬ МНЕ НАДО СЛОЖИТЬ. НА ЭТО ba1=ba1+ba2 - РУГАЕТСЯ
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #14 : Апрель 21, 2010, 16:41 »

QByteArray & QByteArray::append ( const QByteArray & ba )
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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