Russian Qt Forum

Программирование => Общий => Тема начата: __Heaven__ от Апрель 06, 2015, 15:24



Название: [РЕШЕНО] QTextStream и char после 127
Отправлено: __Heaven__ от Апрель 06, 2015, 15:24
Привет, друзья!
Задача:
Записать в текстовый файл значение char в сыром виде через QTextStream.
char может принимать значения от 0х21 до 0x84.

Проблема в том, что после 0x7F (127) char при записи преобразуется в QChar и записывается уже другой символ


Название: Re: QTextStream и char после 127
Отправлено: kambala от Апрель 06, 2015, 16:45
запиши его как rawData через свой QIODevice


Название: Re: QTextStream и char после 127
Отправлено: __Heaven__ от Апрель 06, 2015, 17:25
QString::fromLocal8Bit решил мою проблему

запиши его как rawData через свой QIODevice
Спасибо за ответ, при этом методе нужно делать flush очень часто, что печалит.


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: Авварон от Апрель 06, 2015, 17:30
facepalm
Вот что бывает, когда люди не понимают, что они делают


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: __Heaven__ от Апрель 06, 2015, 17:31
facepalm
Вот что бывает, когда люди не понимают, что они делают
Поясните, пожалуйста


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: Авварон от Апрель 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" - такое впечатление, что вы вообще не совсем с текстом работаете.


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: Igors от Апрель 06, 2015, 18:44
.. звучит как будто вы нашли первый подходящий метод, с которым у вас случайно заработало.
Вы знаете, я бы поступил точно так же, без всяких угрызений совести :)  По-настоящему корректного решения не существует, так или иначе надо подбирать/предполагать кодировку. Конечно спасибо за разъяснения, но то что сделал наш дружок не улучшить.

А вот не-кроссплатформенное решение - пожалуйста. Пишем тип кодировки в resourse fork - и все дела.


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: __Heaven__ от Апрель 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 решил мою проблему" - звучит как будто вы нашли первый подходящий метод, с которым у вас случайно заработало.
Да, так и есть. Вы можете предложить более подходящее решение? Я бы хотел разобраться в этой теме.


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: Old от Апрель 06, 2015, 19:17
Заполняли бы вы QByteArray и его писали бы в файл.
Заодно и текстовые данные сразу туда загоняли в нужной кодировке.


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: __Heaven__ от Апрель 06, 2015, 19:29
Заполняли бы вы QByteArray и его писали бы в файл.
Заодно и текстовые данные сразу туда загоняли в нужной кодировке.

Я с кодировками плохо дружу. Испугало
Цитировать
The contents of array are converted with QString::fromUtf8().


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: Авварон от Апрель 06, 2015, 23:50
Символы неоткуда не приходят. Просто вышеуказанной последовательностью кодируются числа от 0 до 99 (не спрашивайте зачем).

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


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: Igors от Апрель 07, 2015, 08:28
Ну, мне кажется, что совет работать с батареем самый адекватный. У вас есть символы - вот и пишите их файл. То, что все символы читаемы - считайте, что вам повезло, а с файлом работайте как с бинарными данными. Тем более, что у батарея есть основные строковые операции.
Так все ясно, но это уже др задача. Тогда QTextStream вообще не нужен, а читабельность "как получится"


Название: Re: [РЕШЕНО] QTextStream и char после 127
Отправлено: __Heaven__ от Апрель 07, 2015, 09:34
Авварон, я переварил, что вы имели в виду. Я по-своему интерпретировал назначение функции fromLocal8Bit.

Заполняли бы вы QByteArray и его писали бы в файл.
Спасибо. Так и сделаю.