Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: Вывод юникода в консоль на c++  (Прочитано 5866 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн lzv

  • Автор темы
  • Любитель
  • *
  • Сообщений: 89
    • Просмотр профиля
Вывод юникода в консоль на c++
« : 08 Ноября 2012, 10:34:18 »
Здравствуйте.

То ли у меня в консоли что не так настроено, то ли на с++ не так делаю. Помогите пожалуйста разобраться.

Ubuntu 11.04, компилятор g++ 4.5.2, исходники в кодировке utf-8. Пытаюсь вывести в консоль русские символы, определенные в исходнике.

    #include <iostream>
    int main() {
        std::cout << "проверка" << std::endl;
        wchar_t ttest = L'п';
        std::wcout << ttest << std::endl;
        std::cout << "проверка" << std::endl;
        return 0;
    }
Слова "проверка" выводятся нормально, а вместо символа 'п' выводится вопросик. Но что странно, если убрать первый вывод слова "проверка", то оно не выводится и во второй раз!
    #include <iostream>
    int main() {
        wchar_t ttest = L'п';
        std::wcout << ttest << std::endl;
        std::cout << "проверка" << std::endl;
        return 0;
    }
Почему то здесь выводится только вопросик, слово "проверка" не появляется. Если же вместо вывода в wcout написать вывод в cout:
std::cout << ttest << std::endl;вместо символа 'п' выводится число 1087. Однако в этом случае так же выводится и слово проверка. При попытке инициализировать без L:
wchar_t ttest = 'п';Появляется сообщение warning: multi-character character constant.
Если написать так:
std::wcout << L"проверка" << std::endl;то вместо слова "проверка" будет выведено "?@>25@:0". Но это если до вывода был вывод в cout. Если же во всей программе вывод только в wcout, то будут выведены только вопросики.

Пробовал использовать класс wstring, сделал смешанную строку с английскими и русскими буквами. Длинна строки определяется корректно, но при выводе в wcout русские символы показываются вопросиками. Если использовать string, то при выводе в cout все нормально, но длинна строки некорректна.

В консоли кодировка utf-8, исходники тоже в utf-8. Компилирую простейшим образом:
g++ test.cpp -o test
« Последнее редактирование: 08 Ноября 2012, 14:23:42 от lzv »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Вывод юникода в консоль на c++
« Ответ #1 : 08 Ноября 2012, 14:39:33 »
Код: ("C++") [Выделить]

#include <locale>
...

int main() {

// должно помочь
std::locale current_locale("");
std::locale::global(current_locale);

// тоже должно помочь, так можно на разные потоки повесить разные локали
std::wcout.imbue(current_locale);



Оффлайн lzv

  • Автор темы
  • Любитель
  • *
  • Сообщений: 89
    • Просмотр профиля
Re: Вывод юникода в консоль на c++
« Ответ #2 : 08 Ноября 2012, 15:12:10 »
Спасибо, это помогло:

std::locale current_locale("");
std::locale::global(current_locale);

Но такая запись не помогла:

std::locale current_locale("");
std::wcout.imbue(current_locale);

И осталась еще проблема: если до вывода в wcout был вывод в cout, то вывод в wcout отображается некорректно. Например:
#include <iostream>
#include <string>
#include <locale>

int main() {
  std::locale current_locale("");
  std::locale::global(current_locale);

  std::wstring mystr = L"тестtest";
  std::wcout << mystr << std::endl;

  return 0;
}

Результат:
тестtest
Но если написать
#include <iostream>
#include <string>
#include <locale>

int main() {
  std::locale current_locale("");
  std::locale::global(current_locale);

  std::cout << "проверка" << std::endl;
  std::wstring mystr = L"тестtest";
  std::wcout << mystr << std::endl;

  return 0;
}
То результат будет:
проверка
B5ABtest

А если первым в программе был вывод в wcout, то последующий вывод в cout вообще не отобразится, во всей программе будет показан только вывод в wcout.
Хотелось бы разобраться, почему так.

И почему, если заменить std::locale::global(current_locale); на std::wcout.imbue(current_locale); русские символы выводятся вопросиками. Может ли проблема быть в том, что char у меня определен как знаковый, т.е. может кодировать только до 127? Может где-то в глубине кода в него происходит преобразование и выход за диапазон (так как он принципиально кодировать русские символы не может)?
« Последнее редактирование: 08 Ноября 2012, 15:19:07 от lzv »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Вывод юникода в консоль на c++
« Ответ #3 : 11 Ноября 2012, 06:33:06 »
Ну можно почитать документацию на стандартную библиотеку все ответы там

 

Страница сгенерирована за 0.018 секунд. Запросов: 22.