crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> плавающий баг вывода utf8 на stdout
lrx2
  опции профиля:
сообщение 17.2.2017, 15:04
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 12
Регистрация: 7.12.2011
Пользователь №: 3050

Спасибо сказали: 0 раз(а)




Репутация:   0  


Qt Creator 3.2.2 основан на Qt 5.3.2, компилятор minGW 4.9.1
Первый cout печатает, второй - нет.
Если убрать system("chcp"), то печатает все (с крякозябрами).
В чем прикол?

#include <QCoreApplication>

#include <iostream>
using namespace std;

#include <stdio.h>
#include <Windows.h>

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

    system("chcp 65001");
    cout<<"cout 0: rus text : русский  текст"<<endl;
    cout<<"cout 1: after rus text\n";

    return a.exec();
}



Другой код:
#include <QCoreApplication>
#include <iostream>
using namespace std;
#include <Windows.h>

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

    cout<<"default console outputCP: "<<GetConsoleOutputCP()<<"\n";
    cout<<"default console CP: "<<GetConsoleCP()<<"\n";
    cout.flush();

    SetConsoleCP(CP_UTF8);
    SetConsoleOutputCP(CP_UTF8);

    cout<<"new console outputCP: "<<GetConsoleOutputCP()<<"\n";
    cout<<"new  console CP: "<<GetConsoleCP()<<"\n";
    cout.flush();

    cout<<" введите русский текст: ";
    char s[100];
    cin>>s;
    cout<<" вы ввели: ["<<s<<"]";
    cout.flush();

    return a.exec();
}

На одном компе (win 7) после ввода строки и нажатия enter просто переходит на новую строчку и все,
на другом (win 8, minGW 4.8.2 - больше нет отличий):


-----
Я где-то память порвал в этом коде?..
Подскажите нубу.
Спасибо.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 19.2.2017, 23:29
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1636
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 227 раз(а)




Репутация:   12  


а сам код у тебя в UTF? константные строки кодируются как есть.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lrx2
  опции профиля:
сообщение 20.2.2017, 14:13
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 12
Регистрация: 7.12.2011
Пользователь №: 3050

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 19.2.2017, 23:29) *
а сам код у тебя в UTF? константные строки кодируются как есть.

Да, utf-8.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 20.2.2017, 22:31
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1636
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 227 раз(а)




Репутация:   12  


я уже давно не видела венду, но смутно помню, что ей надо было указать русскую локаль в каком-то месте, чтобы она вместо русских букв кракозябры не печатала. плюс для консоли нужно выбрать шрифт, который поддерживает юникод. например, Lucida.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lrx2
  опции профиля:
сообщение 22.2.2017, 4:06
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 12
Регистрация: 7.12.2011
Пользователь №: 3050

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 20.2.2017, 22:31) *
я уже давно не видела венду, но смутно помню, что ей надо было указать русскую локаль в каком-то месте, чтобы она вместо русских букв кракозябры не печатала. плюс для консоли нужно выбрать шрифт, который поддерживает юникод. например, Lucida.

шрифт выбран (Lucida).
setlocale(LC_ALL, "") или setlocale(LC_ALL, "Russian") или setlocale(LC_ALL, "Russian_Russia.1251") трактует строковые константы в коде программы как cp1251 (возвращает строку с именем локали - все хорошо). Кодировка самой консоли на ввод и вывод не меняется(866), судя по getConsoleCP.
(Делал преобразование в CP1251 кода - все выводится нормально)

Если setlocale(LC_ALL, "ru_RU.UTF-8"), то возвращает 0, т.е. - ошибка. В чем ошибка и куда о ней инфу выводить оно должно - не нашел :(
...
std::locale lc_utf8("ru_RU.1251");

выдаёт std::exception что на cp1251, что на utf-8.. не понятно.
------
Суть: setConsoleCP позволяет не только вывод на консоль преобразовывать, но и ввод, чего setlocale не делает.
Вот. Но если бы оно стабильно выводило крякозябры - проблемы бы не было.
Тут же: напечатал код - скомпилил - нормально. Добавил чтение с консоли - появилась мешанина на консоли (часть строки крякозябры-часть нормально-часть вообще из предыдущего cout). Убрал чтение с консоли - опять крякозябры и мешанина.
Возможно, конечно, что я все-таки какие-то мелочи при том упускаю, но пока такое впечатление, либо у меня с башней не особо, либо у компа.(стационар + на ноуте тоже не выходит)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 22.2.2017, 8:05
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2936
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 205 раз(а)




Репутация:   35  


lrx2, а если отбросить всю эту магию и применить QTextCodec ? QString - это юникод, а QTextCodec позволяет гонять из любой кодировки в юникод и наоборот
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lrx2
  опции профиля:
сообщение 22.2.2017, 12:10
Сообщение #7


Студент
*

Группа: Новичок
Сообщений: 12
Регистрация: 7.12.2011
Пользователь №: 3050

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Алексей1153 @ 22.2.2017, 8:05) *
lrx2, а если отбросить всю эту магию и применить QTextCodec ? QString - это юникод, а QTextCodec позволяет гонять из любой кодировки в юникод и наоборот


И так
system("chcp");
    QTextStream cout(stdout);

    cout.setCodec("CP866");
    cout<<QString::fromUtf8("Введите ваше имя: ");
    cout.flush();


    QTextStream cin(stdin);
    cin.setCodec("CP866");
    QString name;
    cin >> name;
    cout << QString::fromUtf8("Привет, ") <<
            name    <<
            "!"     << endl;

и сяк
QTextCodec *coding = QTextCodec::codecForName("866");
    QTextCodec::setCodecForLocale(coding);
    system("chcp 866");

    qDebug() << "qDebug(): русский текст -- ok";
    qWarning() << "qWarning(): русский текст -- ok";
    cout<<"cout: [русский текст] -- not ok\n";


    //------------------------- 2 ----------------------
    cout<<"\n\n----ver2 -----\n";
    QTextStream co(stdout);

    co.setCodec(coding);
    co<<"new codec for locale: [" << QTextCodec::codecForLocale()->name() <<"]";
    co.flush();

    co<<QString::fromUtf8("\nver2: fromUtf8: [русский текст] -- ok\n");
    co<<"ver2: simple: [русский текст] -- not ok \n";
    co.flush();

Работает.
Но локаль - это ж не магия :( Надо бы разобраться..
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 22.2.2017, 14:15
Сообщение #8


Старейший участник
****

Группа: Участник
Сообщений: 908
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 141 раз(а)




Репутация:   9  


Unicode в cmd это магия.
set_locale(LC_ALL, "cp65001") должен сработать, но он очень ненадежный и требует настроек в винде.
http://stackoverflow.com/questions/388490/...ommand-line-how
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 23.2.2017, 5:19
Сообщение #9


Профессионал
*****

Группа: Модератор
Сообщений: 1636
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 227 раз(а)




Репутация:   12  


попробуй инициализировать консоль так:
SetConsoleOutputCP(CP_UTF8);
_setmode(_fileno(stdout), _O_U8TEXT);


проверить не могу, у меня венды нет. но вроде должно работать.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lrx2
  опции профиля:
сообщение 23.2.2017, 22:39
Сообщение #10


Студент
*

Группа: Новичок
Сообщений: 12
Регистрация: 7.12.2011
Пользователь №: 3050

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Iron Bug @ 23.2.2017, 5:19) *
попробуй инициализировать консоль так:
SetConsoleOutputCP(CP_UTF8);
_setmode(_fileno(stdout), _O_U8TEXT);


проверить не могу, у меня венды нет. но вроде должно работать.

в консоли вывода приложения в qt creator выводит: "Invalid parameter passed to C runtime function."
В консольку обычную ничего не пишет: просто курсор мигает и ни на что не реагирует.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2017, 21:46