Поиск:

Ответ в темуСоздание новой темы Создание опроса
> QT - консольные приложения и QCreator 
:(
    Опции темы
tumanovalex
  Дата 29.7.2010, 07:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 3.1.2005

Репутация: нет
Всего: нет



Пытаюсь создать консольное приложение:
Код
#include <QCoreApplication>
#include <QTextStream>
#include <QTextCodec>
#include <conio.h>
 
int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv); 
    QTextCodec *cyrillicCodec = QTextCodec::codecForName("CP1251"); // Пробовал "IBM-866", "UTF-8"
    QTextCodec::setCodecForTr(cyrillicCodec);
    QTextCodec::setCodecForLocale(cyrillicCodec);
    QTextCodec::setCodecForCStrings(cyrillicCodec);
    QTextStream in(stdin), out(stdout); // Нашел в интернете
    out << "Русский текст" << '\n';
    qDebug("Русский текст 2");
    _getch();
    return(0);
}
Появились следующие вопросы:
1. Как правильно настроить вывод русских букв в консоле (при выводе qDebug вместо русских букв знаки вопросов)?
2. Почему не выводится текст в строке out << "Русский текст" << '\n';
3. Есть ли аналог в QT функции _getch()?
4. Можно ли настроить Qcreator так, чтобы при выделении блока можно было его закоментировать по нажатию кнопки (как в Visual Studio) или по горячей клавише?
PM MAIL   Вверх
borisbn
Дата 29.7.2010, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



пробовал так ?
QTextCodec *cyrillicCodec = QTextCodec::codecForName( "Windows-1251" );


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
SABROG
Дата 29.7.2010, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(tumanovalex @  29.7.2010,  07:44 Найти цитируемый пост)
    QTextCodec *cyrillicCodec = QTextCodec::codecForName("CP1251"); // Пробовал "IBM-866", "UTF-8"
    QTextCodec::setCodecForTr(cyrillicCodec);
    QTextCodec::setCodecForLocale(cyrillicCodec);
    QTextCodec::setCodecForCStrings(cyrillicCodec);


Это не правильный код. Мало того, что он не будет корректно работать на других ОС отличных от Windows, так тут еще в одну кашу смешаваются кодировки файла и локали операционной системы.

Поэтому обязательно используй проверку ОС:

Код

/*
Следующий код не верный с точки зрения логики.
Менять кодировку локали не рекомендуется, так как не известно где этот кодек будет потом использоваться внутри самой Qt.
*/
#if defined(Q_WS_WIN)
    if (QLocale::system().country() == QLocale::RussianFederation)
        QTextCodec::setCodecForLocale(QTextCodec::codecForName("IBM866"));
#endif


В Windows локаль по умолчанию cp1251 (для русскоязычного населения, для Украины уже другая будет). Однако кодировка в виндовой консоли "IBM 866" (cp866) (опять же для американцев codepage будет другой). Прописывая кодировки мы автоматически говорим, что приложение пишется для определенной категории людей, наций. Это не правильно. Исходники должны быть написаны либо в UTF-8 кодировке, либо чистый ASCII (Latin-1), где используются только английские символы.

Теперь:

QTextCodec::setCodecForCStrings - по сути задается кодировка в которой написан файл исходника, но используется и для перевода строк char* полученных из других источников.
QTextCodec::setCodecForLocale - специфично для ОС. Может отличаться от codecForCStrings() и в случае с виндой быть не корректным для вывода в консоль русского текста.

QTextStream внутри себя использует codecForLocale()
qDebug() внутри себя используется QTextStream и как следствие использует codecForLocale()

Что получается в итоге. Для Windows, для русских codecForLocale() имеет кодировку windows-cp1251, в то время как кодировка консоли IBM 866 (cp866). Отсюда мы получаем крякозябры. Жестко менять кодировку через setCodecForLocale не корректно.

Стало быть для QTextStream можно использовать установку своего кодека через метод setCodec(), поставить "IBM 866", а для qDebug() видимо остается использовать QString::fromLocal8Bit(), так как кодировку у этого класса поменять нельзя. Или выставлять setCodecForLocale() временно перед выводом сообщения, а после вывода возвращать обратно.

Это сообщение отредактировал(а) SABROG - 29.7.2010, 10:43


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
tumanovalex
  Дата 29.7.2010, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 81
Регистрация: 3.1.2005

Репутация: нет
Всего: нет



Я сделал так:
1. В настройках QCreator я установил в кодировке файла по умолчанию UTF8.
2. Перекодировал Штирлицем файл и поправил.
Правильный вывод получился при таком коде:
Код
  QTextCodec *cyrillicCodec = QTextCodec::codecForName("UTF8");  
  QTextCodec::setCodecForTr(cyrillicCodec);
   QCoreApplication a(argc, argv);
  QTextStream out(stdout);
  QTextCodec *outCodec = QTextCodec::codecForName("IBM866");
  out.setCodec(outCodec);
  out << QObject::tr("Русский текст") << endl;
С qDebug ничего не получилось, на коде qDebug(QString::fromLocal8Bit("Русский текст 2")); выскакивает ошибка функции. Теперь все правильно или я еще где-нибудь допустил ошибку?

PM MAIL   Вверх
SABROG
Дата 30.7.2010, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(tumanovalex @  29.7.2010,  21:18 Найти цитируемый пост)
QString::fromLocal8Bit

Еще бы, у тебя ведь кодировка исходника теперь отличается от кодировки локали.

Вот как надо:

Код

    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

    QTextStream stream(stdout);
#if defined(Q_WS_WIN)
    if (QLocale::system().country() == QLocale::RussianFederation)
        stream.setCodec("IBM866");
#endif
    stream << QString("Защищайте русский лес!\n"); // Right!

// Wrong! Expected Latin-1 (ISO-8859-1), but get UTF-8
// there is no implicit conversion to QString (Unicode)
    stream << "Крякозябры!\n";
    stream << flush;

Код

#if defined(Q_WS_WIN)
    if (QLocale::system().country() == QLocale::RussianFederation)
        QTextCodec::setCodecForLocale(QTextCodec::codecForName("IBM866"));
#endif

    qDebug() << "Трасса в обход!";

#if defined(Q_WS_WIN)
    QTextCodec::setCodecForLocale(0); // return to default
#endif


Обратите внимание, что в случае с QTextStream нужно обязательно указывать конструктор QString(). И забудьте про всякие tr() для перекодировки из одной в другую, это бред какой-то.

Это сообщение отредактировал(а) SABROG - 30.7.2010, 09:32


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
bsa
Дата 21.4.2011, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



SABROG, codecForLocale() под Windows у консольного приложения разве по умолчанию не "IBM 8xx"? Может имеет смысл получать информацию из реестра о текущей OEM кодировке?
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0486 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.