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


За новостями русскоязычного сообщества и Ubuntu в целом можно следить на нашей страничке в Google+

Автор Тема: C++ и кирилица.  (Прочитано 1230 раз)

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

Оффлайн tеma

  • Автор темы
  • Активист
  • *
  • Сообщений: 306
    • Просмотр профиля
C++ и кирилица.
« : 10 Июнь 2011, 18:30:55 »
Начал учить C++, и возникла проблема со следующей программкой:
#include <iostream>
using namespace std;
int main()
{
char symbol1, symbol2, symbol3;

  cout << "Введите свои инициалы через пробел: ";
  cin >> symbol1 >> symbol2;

  cout << "Вы ввели два инициала: ";
  cout << symbol1 << symbol2 << endl;

  cout << "Тоже, но с пробелом: ";
  symbol3 = ' ';
  cout << symbol1 << symbol3 << symbol2 << endl;

  cout << "На этом всё.\n";

return 0;
}
Проблема в следующем: если в программку ввести 2 английских символа, то всё нормально:
Введите свои инициалы через пробел: u k
Вы ввели два инициала: uk
Тоже, но с пробелом: u k
На этом всё.
Однако, если я ввожу русские символы, то получается следующее:
Введите свои инициалы через пробел: о д
Вы ввели два инициала: о
Тоже, но с пробелом: � �
На этом всё.
(только вместо квадратиков -- вопросительные знаки, что вобщем то сути не меняет)
Что не так?
(программа и исходник во вложении)

Lifewalker

  • Гость
Re: C++ и кирилица.
« Ответ #1 : 10 Июнь 2011, 18:56:59 »
Рыть нужно в сторону Unicode и wchar_t.

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #2 : 10 Июнь 2011, 19:18:08 »
tema, спасибо, что заставили меня наконец-то разобраться с wchar_t в C++ :)

#include <iostream>
using namespace std;
int main()
{
  wchar_t symbol1, symbol2, symbol3;

  locale::global(locale(""));

  wcout << L"Введите свои инициалы через пробел: ";
 
  wcin >> symbol1 >> symbol2;

  wcout << L"Вы ввели два инициала: ";
  wcout << symbol1 << symbol2 << endl;

  wcout << L"Тоже, но с пробелом: ";
  symbol3 = ' ';
  wcout << symbol1 << symbol3 << symbol2 << endl;

  wcout << L"На этом всё.\n";

  return 0;
}
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн [DarkNet]Alpha

  • Активист
  • *
  • Сообщений: 987
  • Эмоциональный эльдар
    • Просмотр профиля
    • EBM-радио
Re: C++ и кирилица.
« Ответ #3 : 10 Июнь 2011, 19:35:43 »
symbol3 = ' ';
wcout << symbol1 << symbol3 << symbol2 << endl;
Зачем?

andrey_p

  • Гость
Re: C++ и кирилица.
« Ответ #4 : 10 Июнь 2011, 19:41:27 »
symbol3 = ' ';
wcout << symbol1 << symbol3 << symbol2 << endl;
Зачем?
Для этого наверное... )))
% ./a.out
Введите свои инициалы через пробел: ف ب
Вы ввели два инициала: فب
Тоже, но с пробелом: ف ب
На этом всё.


Оффлайн tеma

  • Автор темы
  • Активист
  • *
  • Сообщений: 306
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #5 : 10 Июнь 2011, 21:12:55 »
Ну вообщем, что я понял: кирилические символы в юникоде сохраняються не 1 байтом, а 2 байтами, из за чего моя прога записывала 1 байт первой буквы в одну переменную, а второй байт первой буквы -- в другую. Поэтому, если они выводились подрят, то давали первую букву, а если через пробел, то 2 крокозябры. Но я пока не особо далеко ушёл в изучении (всего 2 дня занимаюсь), поэтому наверное вернусь к рассмотрунию темы с wchar_t позже. Всем большое спасибо!

Оффлайн [DarkNet]Alpha

  • Активист
  • *
  • Сообщений: 987
  • Эмоциональный эльдар
    • Просмотр профиля
    • EBM-радио
Re: C++ и кирилица.
« Ответ #6 : 11 Июнь 2011, 22:40:34 »
symbol3 = ' ';
wcout << symbol1 << symbol3 << symbol2 << endl;
Зачем?
Для этого наверное... )))
% ./a.out
Введите свои инициалы через пробел: ف ب
Вы ввели два инициала: فب
Тоже, но с пробелом: ف ب
На этом всё.


Ви таки наверное капитан...

wcout << symbol1 << " " << symbol2 << endl;

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #7 : 12 Июнь 2011, 09:55:18 »
как минимум
wcout << symbol1 << L" " << symbol2 << endl;

Оффлайн S_F_H

  • Участник
  • *
  • Сообщений: 129
  • Да будет crossplatform!
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #8 : 24 Июнь 2011, 00:57:04 »
помоему еще можно сделать так:
добавить в функцию main
setlocale(LC_ALL, "Russian");

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #9 : 24 Июнь 2011, 09:52:35 »
помоему еще можно сделать так:
добавить в функцию main
setlocale(LC_ALL, "Russian");

Во-первых, setlocale - это C, а не C++. В C++ вместо неё используется класс locale и в частности его статический метод locale::global.
Во-вторых, строка "Russian" не является корректным названием локали: согласно man setlocale, локаль должна быть указана в формате language[_territory][.code-set][@modifier], где language - код языка согласно ISO 639.
В-третьих, setlocale можно вызвать с пустой локалью "", при этом согласно тому же man setlocale локаль будет настроена в соответствии со значениями переменных окружения.
« Последнее редактирование: 24 Июнь 2011, 09:55:22 от Lion-Simba »
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн S_F_H

  • Участник
  • *
  • Сообщений: 129
  • Да будет crossplatform!
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #10 : 24 Июнь 2011, 10:07:26 »
а разве в с++ это не будет работать? помоему функции С поддерживаються С++

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #11 : 24 Июнь 2011, 10:22:51 »
а разве в с++ это не будет работать? помоему функции С поддерживаються С++
Поддерживаются, но могут быть нюансы как например проблемы синхронизации при совместном использовании в C++ программах cout (C++) и printf() (C).

Проверил, конкретно в данном случае setlocale() работает точно так же как и locale::global(). А вот setlocale(LC_ALL, "Russian") не сработало, чего и следовало ожидать.
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн S_F_H

  • Участник
  • *
  • Сообщений: 129
  • Да будет crossplatform!
    • Просмотр профиля
Re: C++ и кирилица.
« Ответ #12 : 24 Июнь 2011, 10:27:36 »
ну да... мануалы, в которых я нашел эту функцию были написаны для винды))

 

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