Russian Qt Forum

Qt => Общие вопросы => Тема начата: vbi от Февраль 27, 2012, 16:46



Название: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 16:46
Проблема вот в чем. На форме есть поле ввода. Вводим туда текст кирилический, например "тест". Этот текст потом сохраняется в .ini файл.

Если открыть этот файл, то фраза "тест" там будет представлена в форме последовательности из цифр и бекслешей.

Тоесть в файле, фраза "тест" сохранится как "\2102\2065\2101\2102".

Если я потом считываю это значение в поле ввода, оно там отображается нормально как "тест". Но если я считаю его не в поле ввода, а в переменную типа QString оно там остается в текстовом формате как "\2102\2065\2101\2102".

Как эту строку в переменной преобразовать обратно в строку "тест"?


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 16:57
Или нет, даже проще. Допустим у меня на форме есть поле ввода "lineEdit". В него я ввел фразу "тест".

при нажатии на кнопку происходит следующее:

Код:
    QString s = ui->lineEdit->text();
Когда отладчиком проверяю что в "s", отладчик показывает "\2102\2065\2101\210", а не тест. Как его преобразовать в "тест"


Название: Re: Как преобразовать строку QString
Отправлено: mutineer от Февраль 27, 2012, 17:00
Цитировать
QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character.
Это и есть "тест", просто в юникоде. У QString есть ряд методов для преобразования в нужную кодировку, пользуйся ими


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 17:08
Та я и пробую:
Код:
    QByteArray s;

    s.append(ui->lineEdit->text());
    s = ui->lineEdit->text().toAscii();
    s = ui->lineEdit->text().toLatin1();
    s = ui->lineEdit->text().toLocal8Bit();
    s = ui->lineEdit->text().toUtf8();
В первых 3-х случаях присваиваются знаки вопросов. в последних 2-х  - кракозябры


Название: Re: Как преобразовать строку QString
Отправлено: mutineer от Февраль 27, 2012, 17:11
А какая кодировка тебе нужна?


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 17:14
ну по ходу кирилица. Нужно чтоб в "QByteArray s" присвоился "тест". тоесть если сделать:
Код:
qDebug() << s;
то чтоб вывелось слово "тест"


Название: Re: Как преобразовать строку QString
Отправлено: mutineer от Февраль 27, 2012, 17:19
а сейчас в qDebug() что выводится? тот же самый юникод?


Название: Re: Как преобразовать строку QString
Отправлено: Kurles от Февраль 27, 2012, 17:25
ну по ходу кирилица.
;D Кирилических кодировок > 1
Цитировать
Нужно чтоб в "QByteArray s" присвоился "тест". тоесть если сделать:
Код:
qDebug() << s;
то чтоб вывелось слово "тест"
Нужно копать в сторону класса QTextCodec и его функций setCodecForCStrings() и setCodecForLocale().


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 17:28
Если делать так:

Код:
   
    QByteArray s;
    s.append(ui->lineEdit->text());
    qDebug() << s;
    s = ui->lineEdit->text().toAscii();
    qDebug() << s;
    s = ui->lineEdit->text().toLatin1();
    qDebug() << s;
    s = ui->lineEdit->text().toLocal8Bit();
    qDebug() << s;
    s = ui->lineEdit->text().toUtf8();
    qDebug() << s;

На вывод идет:
Цитировать
Отладка запущена
"????"
"????"
"????"
"oano"
"N??µN?N?"


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 17:28
в первых 3-х случаях - знаки вопроса (заминились смайлами)


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 27, 2012, 17:35
Теперь пробую так:
Код:
    QByteArray s;
    QTextCodec *codec = QTextCodec::codecForName("CP1251");
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForTr(codec);
    s.append(ui->lineEdit->text());
    qDebug() << s;
    s = ui->lineEdit->text().toAscii();
    qDebug() << s;
    s = ui->lineEdit->text().toLatin1();
    qDebug() << s;
    s = ui->lineEdit->text().toLocal8Bit();
    qDebug() << s;
    s = ui->lineEdit->text().toUtf8();
    qDebug() << s;

получаю результат:

Цитировать
"òåñò"
"òåñò"
"????"
"òåñò"
"тест"


Название: Re: Как преобразовать строку QString
Отправлено: mutineer от Февраль 27, 2012, 17:41
давай зайдем с другой стороны... Зачем тебе в дебаге видеть нормальную строку?
это ж явно не конечная цель. Где тебе строка нужна в нормальном виде?


Название: Re: Как преобразовать строку QString
Отправлено: Авварон от Февраль 27, 2012, 17:47
Млин, вы такие смешные. В инишнике в качестве ключей могут быть _только_ экранированные символы не латиницы или неэкранированная латиница.
В качестве значений могут быть любые символы. Смотреть метод сет ини кодек у сеттингзов. Хз зачем ставить не утв8 (к-ый по дефолту, кажется)


Название: Re: Как преобразовать строку QString
Отправлено: Kurles от Февраль 27, 2012, 17:52
Только сейчас заметил, что в окно вывода ты QByteArray выводишь - ну дык и не будет русских букв там (в смысле в окне) никогда, ибо QtCreator скомпилирован с поддержкой уникода, a QByteArray этого самого уникода не понимает.


Название: Re: Как преобразовать строку QString
Отправлено: mutineer от Февраль 27, 2012, 17:53
Млин, вы такие смешные. В инишнике в качестве ключей могут быть _только_ экранированные символы не латиницы или неэкранированная латиница.
В качестве значений могут быть любые символы. Смотреть метод сет ини кодек у сеттингзов. Хз зачем ставить не утв8 (к-ый по дефолту, кажется)

Никто не говорил что .ini создается через сеттингс


Название: Re: Как преобразовать строку QString
Отправлено: AlphaGh0St от Февраль 27, 2012, 21:09
Если пишешь под Винду, то, походу, проблема только в кодировке.
Вот код, набросал по быстрому.
http://pastebin.com/iX4qKqmc (http://pastebin.com/iX4qKqmc)
http://pastebin.com/CeRnT6SM (http://pastebin.com/CeRnT6SM)

В поле ввода вводишь строку, жмёшь на кнопку Write. По слоту slotWrite() происходит копирование строки из поля ввода в переменную mainString и запись в файл.
Затем жмёшь на кнопку Read. По слоту slotRead() происходит считывание строки из файла в переменную mainString (типа QString), и в QLabel показывается текст, который содержит эта переменная.


Название: Re: Как преобразовать строку QString
Отправлено: Bepec от Февраль 28, 2012, 07:06
У парня вопрос - как из 1 кодировки в другую перевести, а тут целая дискуссия пошла :)


Название: Re: Как преобразовать строку QString
Отправлено: mutineer от Февраль 28, 2012, 11:04
У парня вопрос - как из 1 кодировки в другую перевести, а тут целая дискуссия пошла :)
Знал бы он в какую


Название: Re: Как преобразовать строку QString
Отправлено: Bepec от Февраль 28, 2012, 12:19
Ну ладно ладно, сам отвечу.

Если ТС работает в windows, то ему скорее всего нужна windows-1251.

Если же он хочет, чтобы юникод(/) был в файле читабельным, ему нужно поставить bom сектор в начале файла, для автоматического распознавания кодировки просмотрщиками.

А решение проблемы произойдет только после ответов автора на некие вопроса, как то:

1) под какой операционной системой пишешь?

2) какая кодировка тебе нужна?

3) в какой кодировке у тебя сохранены исходники? (если незнаешь, то и не отвечай ;))

4) какой IDE работаешь? (Qt Creator/VS)

5) тебе нужно в момент присвоения данных переменной QString вызвать статичную ф-цию QString::fromUtf8(тут как раз массивчик)

и последнее - сделай минимальный компилируемый пример и сбрось в эту тему. Тогда помощь придёт почти мгновенно ;)

Засим откланиваюсь, ваш Верес  ©


Название: Re: Как преобразовать строку QString
Отправлено: sergek от Февраль 28, 2012, 12:27
Можно посмотреть строку при трассировке в QtCreator'e, в окне "Переменные и выражения". Нужно только поставить флажок "Изменить формат отображения/Считать все символы печатными".
И, сдается мне, проблема не в преобразовании текста в различных кодировках, а в самой реализации qDebug. Где-нибудь стоит toLatin1, тупо обрезая таблицу символов.


Название: Re: Как преобразовать строку QString
Отправлено: Bepec от Февраль 28, 2012, 12:44
qDebug работает превосходно.

Вы ему суёте юникод - он показывает latin1, суёте строку, преобразованную в непонятный формат, без установки соответствующего кодека - он показывает latin1(непонятный формат), что равняется кракозябрям с брякозлоидами.


Название: Re: Как преобразовать строку QString
Отправлено: Авварон от Февраль 28, 2012, 14:15
Почему у меня qDebug() выводит в консоль русские буквы, ничего не кракозябая?


Название: Re: Как преобразовать строку QString
Отправлено: Bepec от Февраль 28, 2012, 14:24
Потому что автор читает из файла массив байт, а потом их тупо загооняет в QString без кодеков ;)


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 28, 2012, 16:47
Ну и дискуссия. Я чего-то не мог на форум более суток зайти, писало "Сервер не найден".

На счет qDebug: до этой операции я останавливаю отладчиком и смотрю что в переменную поместилось через отладчик. Так коды символов в QByteArray отличаются от QString.

Значит: пишу под MinGW пока под виндой, но потом хочу прогру и под Linux скомпилить. Кроме того использую мультиязычность. Но в этом маленьком примере и без мультиязычности эта проблема проявляется.

Зачем мне это? я получаю данные от QNetworkReply(), а они в QByteArray - это HTML страница. У меня есть еще переменная QString с киррилическим текстом. Так мне нужно проверить, содержится ли кириллический текст переменной QString в HTML- странице, которая в QByteArray.

Вообще я разработчик парсера Butterfly: http://bibyte.net (http://bibyte.net) его же и тестирую :)

Вот свой пример выложил: bibyte.net/testString.zip (http://bibyte.net/testString.zip)


Название: Re: Как преобразовать строку QString
Отправлено: kambala от Февраль 28, 2012, 16:55
тебе должен подойти один из статических методов QString, какой именно - зависит от кодировки HTML


Название: Re: Как преобразовать строку QString
Отправлено: QuAzI от Февраль 28, 2012, 17:00
Хз зачем ставить не утв8 (к-ый по дефолту, кажется)
Который кажется по дефолту в линухах и то не во всех. Потому что если внимательно посмотреть в настройки QtCreator/Designer, то там видно, что для проекта задаётся системная локаль, если вручную не ткнуть в UTF-8, в свойствах проекта. В итоге от греха подальше тыркается и в свойствах проекта и в первых строках main():
Код:
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
Чтобы спать спокойно за кодировки на любой платформе. Дополнительно для работы с внешними данными (как например прилетающий QByteArray) инициализируется ещё одна переменная класса QTextCodec, в которой и балуемся с кодировками, не ломая кодировки внутри Qt-проекта.


Название: Re: Как преобразовать строку QString
Отправлено: Авварон от Февраль 28, 2012, 18:42
Хз зачем ставить не утв8 (к-ый по дефолту, кажется)
Который кажется по дефолту в линухах и то не во всех. Потому что если внимательно посмотреть в настройки QtCreator/Designer, то там видно, что для проекта задаётся системная локаль, если вручную не ткнуть в UTF-8, в свойствах проекта.
В маке тоже утф-8. Системная локаль - личный косяк кретора (из-за к-ого, кстати, не работает коммит в гит русских букв под виндой - он _почему-то_ в файл коммита пишет в цп1251 (о5 таки в локальной), хотя гит насквозь утф-8й). Попытка использовать отличные от utf локали не приводит ни к чему, кроме косяков.


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 29, 2012, 00:50
Разобрался вобщем я. Проблема была вот в чем: Ошибка в Qt 4.8.0 Когда запускаю отладку - выводит кракозябры. Но когда просто запускаю приложение (без отладки) работает нормально, конвертирует в кириллицу. Так что что-то с отладкой.


Название: Re: Как преобразовать строку QString
Отправлено: sergek от Февраль 29, 2012, 10:17
Это называется "разобрался"? :-\


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 29, 2012, 13:23
Да. В версии 4.8.0 видимо в режиме отладки не правильно работает QTextCodec. Будем ждать обновлений от Nokia когда они исправят проблему. Не буду я копатся в их коде. Некогда мне.


Название: Re: Как преобразовать строку QString
Отправлено: kambala от Февраль 29, 2012, 14:41
интересно почему у меня всё работает прекрасно в отладке с 4.8.0 (файл в кодировке utf-8):
Код
C++ (Qt)
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
QString s("привет");
qDebug() << s;
без кодека естественно выводится чёрт знает что


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Февраль 29, 2012, 19:16
Потому что Вы его не преобразовываете в QByteArray


Название: Re: Как преобразовать строку QString
Отправлено: kambala от Февраль 29, 2012, 20:04
если там заменить QString на QByteArray, ничего не изменится.

если же писать QByteArray b("\u2102\u2065\u2101\u2102"), то с этим по идее ничего нельзя поделать, поскольку системная кодировка - 1251, которая не воспринимает данные символы (об этом даже компилятор заботливо подсказывает).


Название: Re: Как преобразовать строку QString
Отправлено: V1KT0P от Февраль 29, 2012, 22:58
vbi
Только что проверил на 4.8.0 в debug и release при любых способах(естественно окроме toLatin1() для русских символов) работает прекрасно и в ini файле в нормальном UTF-8.
Код:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

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

    MainWindow w;
    w.show();
   
    return a.exec();
}

Код:
void MainWindow::on_loadText_clicked()
{
    QSettings settings("settings.ini", QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    ui->testEdit->setText(settings.value("TestEdit").toString());
    QByteArray s;
    QString text = settings.value("TestEdit").toString();
    qDebug() << text;
    s.append(text.toLocal8Bit());
    qDebug() << s;
    s = text.toAscii();
    qDebug() << s;
    s = text.toLatin1();
    qDebug() << s;
    s = text.toLocal8Bit();
    qDebug() << s;
    s = text.toUtf8();
    qDebug() << s;
}

void MainWindow::on_saveText_clicked()
{
    QSettings settings("settings.ini", QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    settings.setValue("TestEdit", ui->testEdit->text());
}

Тестовый проект: http://rghost.ru/36782654 (http://rghost.ru/36782654)


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Март 01, 2012, 10:28
Скачал Ваш проект, собрал, запустил под отладкой. Ввел слово "Привет", нажал "Save Text", потом "Load Text" - в окне сообщений увидел:
Цитировать
Отладка запущена
"Ïðèâåò"
"Ïðèâåò"
"Ïðèâåò"
"??????"
"Ïðèâåò"
"Ïðèâåò"

Если не в отладке, а просто запустить приложение - то выводит нормально


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Март 01, 2012, 10:35
Вот мои настройки:
(http://i054.radikal.ru/1203/01/dbf3a716bddb.png)


Название: Re: Как преобразовать строку QString
Отправлено: V1KT0P от Март 01, 2012, 13:30
Вот мои настройки:
Вот гифка показывающая что у меня все работает: http://rghost.ru/36788574 (http://rghost.ru/36788574)
У тебя какой версии Qt Creator? 2.4.0?


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Март 01, 2012, 18:47
Да у меня так тоже работает. Неработает когда я на эту (http://s018.radikal.ru/i514/1203/d4/f4fbcd3030df.png) кнопку нажимаю.


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Март 01, 2012, 18:48
Нет, 2.4.1:
(http://s56.radikal.ru/i154/1203/65/e085f5e1220f.png)


Название: Re: Как преобразовать строку QString
Отправлено: V1KT0P от Март 01, 2012, 19:38
Да у меня так тоже работает. Неработает когда я на эту (http://s018.radikal.ru/i514/1203/d4/f4fbcd3030df.png) кнопку нажимаю.
Да действительно какой-то странный баг. Пока не починят можно юзать вот такой костыль:
Код:
void customMessageHandler(QtMsgType type, const char *msg)
{
    QTextCodec *consoleCodec = QTextCodec::codecForName("CP1251");
    QTextStream error(stderr);
    error.setCodec(consoleCodec);
    error << QString::fromUtf8(msg) << endl << flush;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qInstallMsgHandler(customMessageHandler);

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

    MainWindow w;
    w.show();
   
    return a.exec();
}


Название: Re: Как преобразовать строку QString
Отправлено: vbi от Март 02, 2012, 11:53
Спасибо. Это конечно хорошо, но основная цель у меня не на экран выводить, а преобразовать в QByteArray. Я понял что проблема в отладчике, а релиз у меня прекрасно работает, так что этот кусок программы отлаживать не буду. Спасибо за ответы! :)