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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] QTextStream и char после 127  (Прочитано 6484 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Апрель 06, 2015, 15:24 »

Привет, друзья!
Задача:
Записать в текстовый файл значение char в сыром виде через QTextStream.
char может принимать значения от 0х21 до 0x84.

Проблема в том, что после 0x7F (127) char при записи преобразуется в QChar и записывается уже другой символ
« Последнее редактирование: Апрель 06, 2015, 17:26 от __Heaven__ » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #1 : Апрель 06, 2015, 16:45 »

запиши его как rawData через свой QIODevice
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Апрель 06, 2015, 17:25 »

QString::fromLocal8Bit решил мою проблему

запиши его как rawData через свой QIODevice
Спасибо за ответ, при этом методе нужно делать flush очень часто, что печалит.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #3 : Апрель 06, 2015, 17:30 »

facepalm
Вот что бывает, когда люди не понимают, что они делают
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #4 : Апрель 06, 2015, 17:31 »

facepalm
Вот что бывает, когда люди не понимают, что они делают
Поясните, пожалуйста
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #5 : Апрель 06, 2015, 18:14 »

Поясните, пожалуйста

Запомните правило - вы ВСЕГДА должны понимать, в какой кодировке у вас находится ваша 8битная строка - будь то строка в сорцах или считанная в QByteArray.
QTextStream работает над строкой (QString) - всё, что вы пишете в него попадает сперва в эту строку (технически, их 3 - writeBuffer, readBuffer и QString *string - если стрим создан над строкой, а не девайсом).
Таким образом, все, что вы в него пишете, сперва перекодируется (это важно!) в UTF-16, в котором работает QString. Перекодировка ВСЕГДА осуществляется кодеком. Внимание вопрос - каким? Ответ на это дает документация:
Код:
QTextStream & QTextStream::operator<<(const char * string)
This is an overloaded function.

Writes the constant string pointed to by string to the stream. string is assumed to be in ISO-8859-1 encoding.
ISO-8859-1 - это Latin1, т.е. символы с кодом, меньшим 127.
Таким образом, ваше утверждение неверно ("после 0x7F (127) char при записи преобразуется в QChar"). char ВСЕГДА преобразуется в QChar используя предположение, что этот char находится в latin1 кодировке:
Код:
QChar::QChar(char ch)
Constructs a QChar corresponding to ASCII/Latin-1 character ch.

Дальше возникает вопрос - откуда пришел символ. Если он пришел из файла, то fromLocal8Bit будет, возможно, неверным методом, так как ваш файл не смогут прочитать на других платформах (в файлах лучше всего использовать utf-8, вендовый блоктон отлично его понимает). Если файл сделан другой программой то да, тогда нужен local8Bit. "QString::fromLocal8Bit решил мою проблему" - звучит как будто вы нашли первый подходящий метод, с которым у вас случайно заработало.

Далее - "при этом методе нужно делать flush очень часто, что печалит."
Снова неверно, ровно также часто, как это делает QTextStream (а делает он это в деструкторе\при смене девайса)

А ну и да, "0х21 до 0x84" - такое впечатление, что вы вообще не совсем с текстом работаете.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Апрель 06, 2015, 18:44 »

.. звучит как будто вы нашли первый подходящий метод, с которым у вас случайно заработало.
Вы знаете, я бы поступил точно так же, без всяких угрызений совести Улыбающийся  По-настоящему корректного решения не существует, так или иначе надо подбирать/предполагать кодировку. Конечно спасибо за разъяснения, но то что сделал наш дружок не улучшить.

А вот не-кроссплатформенное решение - пожалуйста. Пишем тип кодировки в resourse fork - и все дела.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Апрель 06, 2015, 18:59 »

Я работаю не с текстом, но выходной файл при этом текстовый и разделён на блоки текст/данные, готовлю файл для съедения другой программе.
Перед тем как поставить вопрос использовал функцию
Код
C++ (Qt)
QTextStream &QTextStream::operator<<(char c)
{
   Q_D(QTextStream);
   CHECK_VALID_STREAM(*this);
   d->putString(QString(QChar::fromLatin1(c)));
   return *this;
}
Символы неоткуда не приходят. Просто вышеуказанной последовательностью кодируются числа от 0 до 99 (не спрашивайте зачем).
"QString::fromLocal8Bit решил мою проблему" - звучит как будто вы нашли первый подходящий метод, с которым у вас случайно заработало.
Да, так и есть. Вы можете предложить более подходящее решение? Я бы хотел разобраться в этой теме.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #8 : Апрель 06, 2015, 19:17 »

Заполняли бы вы QByteArray и его писали бы в файл.
Заодно и текстовые данные сразу туда загоняли в нужной кодировке.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #9 : Апрель 06, 2015, 19:29 »

Заполняли бы вы QByteArray и его писали бы в файл.
Заодно и текстовые данные сразу туда загоняли в нужной кодировке.

Я с кодировками плохо дружу. Испугало
Цитировать
The contents of array are converted with QString::fromUtf8().
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #10 : Апрель 06, 2015, 23:50 »

Символы неоткуда не приходят. Просто вышеуказанной последовательностью кодируются числа от 0 до 99 (не спрашивайте зачем).

Ну, мне кажется, что совет работать с батареем самый адекватный. У вас есть символы - вот и пишите их файл. То, что все символы читаемы - считайте, что вам повезло, а с файлом работайте как с бинарными данными. Тем более, что у батарея есть основные строковые операции.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Апрель 07, 2015, 08:28 »

Ну, мне кажется, что совет работать с батареем самый адекватный. У вас есть символы - вот и пишите их файл. То, что все символы читаемы - считайте, что вам повезло, а с файлом работайте как с бинарными данными. Тем более, что у батарея есть основные строковые операции.
Так все ясно, но это уже др задача. Тогда QTextStream вообще не нужен, а читабельность "как получится"
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #12 : Апрель 07, 2015, 09:34 »

Авварон, я переварил, что вы имели в виду. Я по-своему интерпретировал назначение функции fromLocal8Bit.

Заполняли бы вы QByteArray и его писали бы в файл.
Спасибо. Так и сделаю.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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