Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt и кодировки.  (Прочитано 15202 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« : 05-07-2016 13:00 » 

Добрый день.

Хочу получить ликбез вот по какому вопросу: сейчас пользуюсь Qt Creator, кодировка в редакторе стоит UTF-8, компилирую под Windows, который, как я понимаю использует cp1251. Соответственно, в консольном приложении текст на русском не выводится. Переключать кодировку редактора не вижу смысла, так как помимо Windows хотелось бы сохранить возможность безпроблемной компиляции под Linux с кодировками, как UTF-8, так и ISO 8859.
Переключение локали нужный результат не даёт или я это неверно понимаю.

В целом я хотел бы понять, как необходимо оформить приложение, чтобы изначальный текст, написанный в UTF-8 правильно портировался на разные платформы.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 05-07-2016 14:51 » 

В GUI, я так понимаю, проблемы кодировок нет? Т.е. проблема чисто виндовой консоли, а не приложения. Пример решения: http://anvarichn.livejournal.com/43752.html
Если очень хочется без chcp, то напиши обертку вывода в консоль, где будешь перекодировать в OEM (для кириллицы это cp866, а не cp1251!). Но, черт побери, это каменный век!
« Последнее редактирование: 05-07-2016 14:53 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 05-07-2016 15:43 » 

В GUI, я так понимаю, проблемы кодировок нет? Т.е. проблема чисто виндовой консоли, а не приложения.
Я так понял, да, хотя серьёзного тестирования по этой теме не делал - по умолчанию многое пишу на английском, чтобы избежать возможных проблем.

Кстати, вот, специально пишу в блокноте Windows 10:
Код:
#include <locale.h>
#include <stdio.h>

int main (void)
{
printf("123 Text Текст\n");
char* p_locale = setlocale(LC_ALL, "");
printf("123 Text Текст\n");
printf("%s", p_locale);
return 0;
}

Компиляция в tcc, вывод в консоли:
123 Text ╥хъёЄ
123 Text Текст
Russian_Russia.1251

Результат: получается блокнот работает в cp1251, консоль изначально в cp866, после вызова setlocale переключает консоль в cp1251? Хотя вызов без параметра по идее должен возвращать текущую системную локаль, а не изменять её.

Хорошо, а если кириллицей не ограничиваться? Возможно есть более прямой путь?
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 05-07-2016 16:10 » 

Насколько Я помню, в Qt была возможность перевода строк. Можно наверно ее использовать. Т.е. один вариант пишеш в одной кодировке. Второй вариант в другой.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 06-07-2016 05:00 » 

у меня редактор использует utf8, все исходники тоже на utf8 делаю (единственное, что компилятор почему-то желает в ansi - это *.pri , там комментарии особо не парясь транслитом пишу Отлично )

QString использует юникод, поэтому через него можно делать преобразования кодировок (X->unicode->Y)

например, работаем с 1251
Код:
#include <QTextCodec>
...
//кодек Windows-1251
const QTextCodec* p=QTextCodec::codecForName("Windows-1251");

...  =  p->toUnicode(...)
...  =  p->fromUnicode(...)

Добавлено через 3 минуты и 10 секунд:
или, наверное, нужно будет использовать вызов

Код:
void QTextCodec::setCodecForLocale(QTextCodec * c)

сам я с этой функцией не разбирался, пробуй
« Последнее редактирование: 06-07-2016 05:04 от Алексей1153 » Записан

darkelf
Молодой специалист

ua
Offline Offline

« Ответ #5 : 06-07-2016 05:34 » 

Если не совсем Qt, ну и плюс - использование microsoft-специфичных расширений и только для кириллицы, то можно что-то типа такого:

Код: (C)
#include <stdio.h>
#include <locale.h>

#pragma setlocale(".1251")

int main(int argc, char* argv[])
{
  setlocale(LC_ALL, ".OCP");
  wprintf(L"%s", L"Здравствуй, мир!\n");

  return 0;
}

Сам исходник набран в кодировке 1251, но корректно отображает сообщения в консоли.

Более правильным, имхо, будет использование средств переводов Qt.
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 06-07-2016 17:50 » 

Насколько Я помню, в Qt была возможность перевода строк.
Как я понял tr - это языковая интернализация, то есть всё в рамках кодировки utf-8, но к проекту прибавляется файл с переводами, в итоге можно сделать быстрый перевод приложения на нужный язык.

QString использует юникод, поэтому через него можно делать преобразования кодировок (X->unicode->Y)
Посмотрел, странно, но не работает? Хотя должно, вроде как с третьей версии присутствует. Попробую ещё вывод в файл потестить через эти функции в разных кодировках, возможно у потоков вывода в консоль есть свои нюансы.

Код: (C)
...
int main(int argc, char* argv[])
{
  setlocale(LC_ALL, ".OCP");
  wprintf(L"%s", L"Здравствуй, мир!\n");

  return 0;
}
Сам исходник набран в кодировке 1251, но корректно отображает сообщения в консоли.
Интересно, 1251, если я правильно помню однобайтная кодировка, как и 866. Как в этом случае её переводят в wchar_t? Обычно под ним скрывается ushort, значит старший байт заполняется нулём. Как в этом случае работает L?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #7 : 07-07-2016 05:24 » 

Интересно, 1251, если я правильно помню однобайтная кодировка, как и 866. Как в этом случае её переводят в wchar_t? Обычно под ним скрывается ushort, значит старший байт заполняется нулём. Как в этом случае работает L?
За счёт #pragma setlocale() компилятор может правильно преобразовать текст в кодировке 1251 в UTF-16. В gcc есть нечто подобное, но задающееся через ключ командной строки -finput-charset=. По поводу tcc к сожалению ничего сказать не могу.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 07-07-2016 08:41 » 

Интересно, 1251, если я правильно помню однобайтная кодировка, как и 866. Как в этом случае её переводят в wchar_t? Обычно под ним скрывается ushort, значит старший байт заполняется нулём. Как в этом случае работает L?
L должно работать как написано: делать wchar_t сразу, на этапе компиляции. В зависимости от компилятора, получается UTF-16 (Visual Studio и иные Win-компиляторы) или UTF-32 (GCC). Cтарший байт (или три байта, в Linux&Co) не обязательно будет нулём - это верно только для части основных символов типа латиницы и цифр.
Соответственно, кодируется всё из одной таблицы в другую: в WinAPI, скажем, есть функции MultiByteToWideChar и обратно, а в стандартной библиотеке есть свои методы.
« Последнее редактирование: 07-07-2016 08:54 от Вад » Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 07-07-2016 19:23 » new

Спасибо, понимание появляется.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines