Проблемы с вводом русских букв в терминале

Для новичков как вообще в Linux, так и в конкретной теме, к которой относится вопрос.

Модератор: Bizdelnick

K_AA
Сообщения: 5
ОС: Ubuntu 12.10

Проблемы с вводом русских букв в терминале

Сообщение K_AA »

Выявилась такая вот проблема.
При вводе слов на русском языке из терминала некорректно срабатывает удаление символов.

Вот та часть кода:

Код: Выделить всё

   string str;
   cin >> str;


Если ввести слово с первого раза, то всё в порядке. Но если, допустим, при вводе мы допускаем ошибку и удаляем, а затем продолжаем вводить слово, то результат будет некорректным.

Например:
1) вводим "Слон";
2) удаляем букву "н", при этом на экране остается "Сло";
3) продолжаем ввод "во", на экране остается "Слово".
4) теперь выводим введённое слово в терминал, получаем "Сло?во", где вместо знака вопроса стоит какой-то левый символ.


С английским языком таких проблем нету.
Как я понял, дело в том, что английские символы кодируются одним байтом, а русские двумя. При нажатии Backspace буква с экрана исчезает, но её код стирается не полность из буфера, а только младший байт. Старший при этом сохраняется и затем записывается в строковую переменную.

А теперь сам вопрос, как с этим бороться? Мне нужно, чтобы при нажатии Backspace стирался весь русский символ, а не его младший байт...
Или может возможно временно сменить кодировку при вводе/выводе в терминал, чтобы все символы кодировались одним байтом? Но как это сделать, не нашел...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX

Re: Проблемы с вводом русских букв в терминале

Сообщение Olej »

K_AA писал(а):
28.03.2013 18:46
Например:
1) вводим "Слон";
2) удаляем букву "н", при этом на экране остается "Сло";
3) продолжаем ввод "во", на экране остается "Слово".
4) теперь выводим введённое слово в терминал, получаем "Сло?во", где вместо знака вопроса стоит какой-то левый символ.


Это не "непонятный символ", а 1/2 символа :rolleyes: - Linux сейчас использует UTF-8 кодировку (для представления UNICODE символов), в UTF-8 каждая русская литера представляется 2-мя символами, а ваш <Backspace> забивает только один. Вам ещё повезло - в некоторых языковых таблицах символ будет представляться UTF-8 до 4-х символов :rolleyes:

K_AA писал(а):
28.03.2013 18:46
А теперь сам вопрос, как с этим бороться? Мне нужно, чтобы при нажатии Backspace стирался весь русский символ, а не его младший байт...
Или может возможно временно сменить кодировку при вводе/выводе в терминал, чтобы все символы кодировались одним байтом? Но как это сделать, не нашел...

На современных дистрибутивах Linux такого не должно наблюдаться.
Какой у вас?
Это зависит от настроект типа терминала, при некоторых настройках так бывает ... в сесси SSH бывает и т.д.

K_AA писал(а):
28.03.2013 18:46
Вот та часть кода:

Код: Выделить всё

   string str;
   cin >> str;

Но если речь идёт о собственном программном коде (С++), то здесь нужно делать правильную локализацию потоков ввода-вывода: переносимость Lin<=>Win консольных приложений.
Спасибо сказали:
K_AA
Сообщения: 5
ОС: Ubuntu 12.10

Re: Проблемы с вводом русских букв в терминале

Сообщение K_AA »

Вообще пишу из под Ubuntu 12.10, но программа будет перекомпилирована под другую версию, работающую на небольшом терминале. Это курсовая работа такая у нас, написать программу для терминала ВИП МК.

Только щас получил доступ к документам по этому терминалу и выяснил, что там используется кодировка KOI8-R. Если я правильно понял, там все символы по 1 байту, и вышеописанной проблемы не будет?
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX

Re: Проблемы с вводом русских букв в терминале

Сообщение Olej »

K_AA писал(а):
01.04.2013 05:21
Только щас получил доступ к документам по этому терминалу и выяснил, что там используется кодировка KOI8-R. Если я правильно понял, там все символы по 1 байту, и вышеописанной проблемы не будет?

Проблема может быть, может не быть ... но вы посмотрите ссылку что я дал выше: локализацию нужно нормально сделать в коде.
Например так:

Код: Выделить всё

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

Или:

Код: Выделить всё

cout.imbue( locale( "" ) );
cin.imbue( locale( "" ) );


Хорошая программа должна работать правильно независимо от того, какой там будет терминал ... и даже если она попадёт в Windows. ;)
Спасибо сказали:
K_AA
Сообщения: 5
ОС: Ubuntu 12.10

Re: Проблемы с вводом русских букв в терминале

Сообщение K_AA »

Olej писал(а):
01.04.2013 10:48
K_AA писал(а):
01.04.2013 05:21
Только щас получил доступ к документам по этому терминалу и выяснил, что там используется кодировка KOI8-R. Если я правильно понял, там все символы по 1 байту, и вышеописанной проблемы не будет?

Проблема может быть, может не быть ... но вы посмотрите ссылку что я дал выше: локализацию нужно нормально сделать в коде.
Например так:

Код: Выделить всё

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

Или:

Код: Выделить всё

cout.imbue( locale( "" ) );
cin.imbue( locale( "" ) );


Хорошая программа должна работать правильно независимо от того, какой там будет терминал ... и даже если она попадёт в Windows. ;)



Внутри "" пишется название кодировки, типа UTF-8 или KOI8-R ?
Всё равно спасибо, опробую.
Спасибо сказали:
Аватара пользователя
Olej
Сообщения: 659
ОС: Fedora, Mint, Debian, QNX

Re: Проблемы с вводом русских букв в терминале

Сообщение Olej »

K_AA писал(а):
01.04.2013 11:53
Внутри "" пишется название кодировки, типа UTF-8 или KOI8-R ?
Всё равно спасибо, опробую.


Нет, внутри пишется именно пустая строка "", что расшифровывается :rolleyes: как : "использовать локализацию ОС, по умолчанию".

А вот с явной записью имени локализации (это не кодировка) - вот тут как-раз у вас начнутся проблемы:
- в Windows KOI-8r должна записываться как "Russian_Russia.20866" ...
- в Linux KOI-8r должна записываться как "ru_RU.koi8r"
- а если вы запишете неправильную строку локализации (например, "ru_RU.1251"), то тут же поймаете exeption с аварийным завершением программы.

Сделайте в своём Linux:

Код: Выделить всё

bash-4.2$ locale -a | grep ru
ru_RU
ru_RU.iso88595
ru_RU.koi8r
ru_RU.utf8
...

И вы увидите все известные системе локализации в правильном написании.
Спасибо сказали: