Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.59/22: Рейтинг темы: голосов - 22, средняя оценка - 4.59
1 / 1 / 0
Регистрация: 15.01.2021
Сообщений: 33

Неправильный вывод в консоль русского языка

23.08.2021, 13:12. Показов 4795. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу "Шифр Цезаря", заменяю буквы в введенном тексте с шагом 2 (например), следовательно "абаб" должно преобразоваться в "вгвг", что и находится в переменной InputText. Только в консоль выводится "туту" почему-то. Как решить проблему?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include "Cesar.h"
#include <locale>
#include <Windows.h>
#include <string>
using namespace std;
 
 
int cesar()
{
    int step;
    cout << " Введите ключ для зашифровывания текста: \n ";
    cin >> step;
    char InputText[255];
    cout << " Введите текст, который хотите закодировать: " << endl;
    SetConsoleCP(1251);
    cin >> InputText;
    int len = strlen(InputText);
   
    for (int i = 0; i < len; i++)
    {
        if (step >= 0)
            InputText[i] = (InputText[i] - 'а' + step) % 32 + 'а';
        else
            InputText[i] = (InputText[i] - 'а' + 32 + step) % 32 + 'а';
    } 
    cout << InputText << endl;
    SetConsoleCP(866);
    system("pause");
  
    return 0;
}
Миниатюры
Неправильный вывод в консоль русского языка  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.08.2021, 13:12
Ответы с готовыми решениями:

Вывод русского языка в консоли
Доброго времени суток, коллеги! Столкнулся с проблемой при написании простенькой программы шифрования/дешифрования текста: после...

Ввод/вывод с использование русского языка
Мне нужно ввести с клавиатуры строку на русском языке (например:&quot;Я живу в России&quot;) и вывести её также. Как это сделать? Я сколько не...

Неправильный вывод кириллицы в консоль
Здравствуйте уважаемые форумчане. Нуждаюсь в Вашем совете. Моя программа(ка :-непонятные символы. При этом в файл все выводится как надо. ...

35
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
24.08.2021, 15:08
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ram876 Посмотреть сообщение
Раз все критикуют старые решения, тогда предложите, пожалуйста, решение на чистом c++, которое не будет зависеть от платформы.
Мне кажется, что единственного способа не существует.
Единственный выход использование фреймворков, или личных костылей в виде определения системы (во время компиляции) и выбор правильного способа установки локали.

Цитата Сообщение от мама Стифлера Посмотреть сообщение
но его ОС использует по умолчанию кодировку 866
866 по умолчанию только для консоли, и только под Windows.
А вообще тема довольно серьезная и обширная.

На правильное отображения влияют несколько факторов.
- Кодировка исходного кода программы. (в MSVC 2015 это никак не влияет, студия об этом уже позаботилась)
- установка std::locale, она обязательно (по умолчанию) влияет на текстовый ввод/вывод используя региональные (языковые) особенности.
- настройка самой консоли, в случае если locale по какой то причине этого не сделала или сделала неправильно.
- ну и наконец поддержка ОС кодировок (того же ЮНИКОДА, или utf-8).
- да, чуть не забыл, наличие шрифтов в системе для отображения символов Юникода тоже как бы нужно, наверное

Довольно недавно начал интересоваться мультиязычностью, в частности Юникодом.
И это не такая простая тема, охватывая ее в контексте кросс-платформености.

Цитата Сообщение от Замабувараев Посмотреть сообщение
Рекомендую использовать функции с W на конце и забыть про кодировки.
и забыть про кодировки, ну - ну ...
0
из племени тумба-юбма
 Аватар для мама Стифлера
2523 / 1819 / 419
Регистрация: 29.11.2015
Сообщений: 8,857
Записей в блоге: 15
24.08.2021, 15:12
Цитата Сообщение от qppq Посмотреть сообщение
пишу так
Ну тогда поток вывода будет в кириллице, а поток ввода останется по дефолту(юникод вроде). Поэтому лучше использовать связку строк
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
.
//или
.
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
.
//или
.
.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
24.08.2021, 15:20
Цитата Сообщение от SmallEvil Посмотреть сообщение
и забыть про кодировки, ну - ну ...
Да, потому что есть функции ReadConsoleW и WriteConsoleW, которые сразу работают с юникодом.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
24.08.2021, 15:43
Цитата Сообщение от Замабувараев Посмотреть сообщение
ReadConsoleW и WriteConsoleW
Это только Windows приблуды.

Я лишь хочу сказать что избавится от работы с кодировками не получится.
Для экономии места и сетевого трафика, мультиязычный Юникод кодируется в UTF-8
(сжимается, и довольно не плохо, в зависимости от содержимого).

То-есть, перед записью/чтении в файл или получения/отправки по сети его нужно перекодировать.

И еще , есть коды, библиотеки, сохраненные базы в других кодировках, которые работают/сохранены старыми кодировками только с string, char *, которые кодировать также придется.

То есть твой простой совет про Виндовс функции с W на самом деле не избавит от работы с кодировками.
Даже внутри одной системы, не говоря о переносимости.

Добавлено через 1 минуту
И как я уже написал выше, установка локализации влияет на форматирование, чисел , дат, денежных записей, и т.д.
Не нужно об этом забывать.

Добавлено через 2 минуты
То есть, я пытаюсь донести что кодировка и локаль (локализация) не одно и то же.
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
24.08.2021, 16:25
Цитата Сообщение от SmallEvil Посмотреть сообщение
Это только Windows приблуды.
SetConsoleCP и SetConsoleOutputCP — тоже только «Windows приблуды». Вместо них Я рекомендую выводить строки юникодными функциями ReadConsoleW и WriteConsoleW сразу.
К тому же, манипуляции кодировками — это дурной тон. Программа должна либо получать кодировку которая сейчас установлена в консоли и перекодировать строку в неё, либо сразу выводить юникод. Иначе смена кодировки — это то же самое что перемещение значка корзины на вашем рабочем столе в другое место «потому что программе так удобно».
Цитата Сообщение от SmallEvil Посмотреть сообщение
То-есть, перед записью/чтении в файл или получения/отправки по сети его нужно перекодировать.
И еще , есть коды, библиотеки, сохраненные базы в других кодировках, которые работают/сохранены старыми кодировками только с string, char *, которые кодировать также придется.
То есть твой простой совет про Виндовс функции с W на самом деле не избавит от работы с кодировками.
Даже внутри одной системы, не говоря о переносимости.
Функции WinAPI работающие со строками есть только в одном варианте: юникодном UTF-16. Другие, что принимают ANSI‐строки — это лишь оболочки над W‐функциями. Настоящую работу A‐функции не делают, внутри себя они лишь гоняют байты туда‐сюда вызывая W‐функции, перекодируют строки (с потерей информации).
Если вам нужны эффективные программы, то рекомендую вам игнорировать A‐функции и сразу вызывать W‐функции.
Кроме того, некоторые функции есть только в юникодном варианте (например, CommandLineToArgvW).
0
 Аватар для COKPOWEHEU
4070 / 2704 / 433
Регистрация: 09.09.2017
Сообщений: 12,026
24.08.2021, 16:49
Цитата Сообщение от Замабувараев Посмотреть сообщение
SetConsoleCP и SetConsoleOutputCP — тоже только «Windows приблуды».
...которые приходится выносить в слой совместимости, как и прочие костыли.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Вместо них Я рекомендую выводить строки юникодными функциями ReadConsoleW и WriteConsoleW сразу.
То есть вместо человеческого, кроссплатформенного и гибкого ввода-вывода вы предлагаете очередной костыль, который мало того что непереносим, так еще и вводить ничего кроме строк не может.
Даже интересно, как вы на этом чуде подоконной техники будете реализовывать нормальный ввод-вывод.
Открыл документацию на эту функцию

https://docs.microsoft.com/ru-... eadconsole
Функция Реадконсоле

Считывает входные символы из буфера ввода консоли и удаляет его из буфера.
Синтаксис

BOOL WINAPI ReadConsole(
_In_ HANDLE hConsoleInput,
_Out_ LPVOID lpBuffer,
_In_ DWORD nNumberOfCharsToRead,
_Out_ LPDWORD lpNumberOfCharsRead,
_In_opt_ LPVOID pInputControl
);

Параметры

хконсолеинпут [ окне]
Маркер входного буфера консоли. Этот дескриптор должен иметь право доступа GENERIC_READ. Дополнительные сведения см. в статье Безопасность и права доступа для буфера консоли.

лпбуффер [ заполняет]
Указатель на буфер, который получает данные, считанные из входного буфера консоли.

ннумберофчарстореад [ окне]
...
Все режимы ввода, влияющие на поведение ReadFile , имеют тот же результат в реадконсоле. Чтобы получить и задать режимы ввода входного буфера консоли, используйте функции жетконсолемоде и сетконсолемоде .
и далее в том же духе
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
24.08.2021, 16:54
COKPOWEHEU, так надо на английский переключать
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
24.08.2021, 17:30
COKPOWEHEU, ваш «человеческий, кроссплатформенный и гибкий ввод‐вывод» std::wcout и std::wstring не работает, и вам приходится применять костыли с кодировками.
Во‐вторых, юникод в Windows — это UTF-16. Я не знаю, почему ваши разработчики библиотек std::wcout, std::wstring и прочих не могут этого понять чтобы сделать кроссплатформенное решение.
В‐третьих, у WinAPI богатый набор консольных функций, а не одна «вывод в файл».
0
 Аватар для COKPOWEHEU
4070 / 2704 / 433
Регистрация: 09.09.2017
Сообщений: 12,026
25.08.2021, 09:07
Цитата Сообщение от Алексей1153 Посмотреть сообщение
COKPOWEHEU, так надо на английский переключать
Или ждать пока в майкрософт осилят наконец юникод. Сейчас же проблема именно в этом: консоль приходится переключать в ПЯТИ местах, и то не хватает.
Цитата Сообщение от Замабувараев Посмотреть сообщение
COKPOWEHEU, ваш «человеческий, кроссплатформенный и гибкий ввод‐вывод» std::wcout и std::wstring не работает
Зачем вы врете?
Он не работает только в wine, а на реальной винде работает. Не говоря про другие системы.
Цитата Сообщение от Замабувараев Посмотреть сообщение
и вам приходится применять костыли с кодировками.
Неа, я пользуюсь wprintf и даже не подозревал что ваши std::wcout имеют какие-то проблемы.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Во‐вторых, юникод в Windows — это UTF-16. Я не знаю, почему ваши разработчики библиотек std::wcout, std::wstring и прочих не могут этого понять чтобы сделать кроссплатформенное решение.
Лучше скажите почему в вашей виндовс до сих пор не осилили перейти на юникод? До сих пор все эти извращения с cp1251, 866 и utf-16 (который вообще ни туда ни сюда).
Цитата Сообщение от Замабувараев Посмотреть сообщение
В‐третьих, у WinAPI богатый набор консольных функций, а не одна «вывод в файл».
То есть предлагаете сначала программу писать нормально, а потом переписывать под ваши экзотические функции?
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
25.08.2021, 09:29
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Или ждать пока в майкрософт осилят наконец юникод
да я про статью на сайте - чтобы перевод кривой не читать
0
 Аватар для COKPOWEHEU
4070 / 2704 / 433
Регистрация: 09.09.2017
Сообщений: 12,026
25.08.2021, 09:49
Алексей1153, это-то ладно, зато читать забавно.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
25.08.2021, 11:52
Ну и маленький итог для Замабувараев :
Лучше раз создать костыль для установки локали/кодировок и остальной код будет неизменен(почти полностью),
и удобен в работе.
Чем написать только для Windows (еще и нахлебаться при этом дермища с ее супер функциями АПИ).
Но естественно конечный продукт, рассчитанный только на Windows, можно писать и так.
И даже тут, на разные семейства ОС Windows, будешь костылять
0
 Аватар для vlisp
1070 / 991 / 153
Регистрация: 10.08.2015
Сообщений: 5,416
26.08.2021, 08:59
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
То есть вместо человеческого, кроссплатформенного и гибкого ввода-вывода
все говорят про нормальный человеческий, но никто не приводит ни одного примера
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
26.08.2021, 09:18
Если какие‐то cin и cout не умеют правильно вводить и показывать строки, то очевидно, что эти библиотеки кривые и не работают. Я не знаю зачем нужно пользоваться тем что не работает, видимо, какая‐то разновидность доставить себе боль и разочарование.
Напротив, прямые вызовы операционной системы работают. Чтобы починить корявые cin и cout вы всё равно используете WinAPI, несмотря на психологический пунктик против WinAPI. А в итоге починка не удаётся.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.08.2021, 09:42
SmallEvil, Не выводятся wchar_t символы (может быть будет полезно)
0
 Аватар для COKPOWEHEU
4070 / 2704 / 433
Регистрация: 09.09.2017
Сообщений: 12,026
26.08.2021, 21:07
Цитата Сообщение от vlisp Посмотреть сообщение
все говорят про нормальный человеческий, но никто не приводит ни одного примера
Вот наиболее приближенный к человеческому вывод (ввод майкрософты как-то хитро поломали, я не нашел способа его настроить):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#ifdef WIN32
  #include <windows.h>
  #include "fcntl.h"
  __attribute__((constructor)) void coninit(){
    SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8);
    _setmode(_fileno(stdout), _O_U8TEXT);
    _setmode(_fileno(stdin), _O_U8TEXT);
  }
#endif
 
int main(){
#ifdef WIN32
  coninit();
#endif
  setlocale(LC_ALL, "");
  wprintf(L"x\u00B2+7x+4\n");
  return 0;
}
В отличие от варианта с std::wcout, этот работает и в wine тоже.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Я не знаю зачем нужно пользоваться тем что не работает, видимо, какая‐то разновидность доставить себе боль и разочарование.
Правильно! Если с std::wcout проблемы, просто не пользуемся им. wprintf работает нормально.
Цитата Сообщение от Замабувараев Посмотреть сообщение
Напротив, прямые вызовы операционной системы работают.
Конечно. Но только в той операционной системе. Поэтому вместо ручной реализации ввода-вывода на низкоуровневых системных функциях стоит максимально использовать высокоуровневый ввод-вывод, который уже написан разработчиками.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.08.2021, 21:07

Неправильный вывод в консоль
Всем привет, задали задачу: Напишите программу, которая создает поток. Используйте атрибуты по умолчанию. Родительский и вновь...

Как исправить вывод русского языка
Я скачал программу на сайте хотел запустить и походу не хватает каких то библиотек у меня. Скажите что нужно добавить? Написаны...

Ввод и вывод русского языка в консоли а именно в классе
Данный код для вывода и ввода русского языка я использовал в головной функции файла cpp, но в классе он не работает как сделать так чтобы...

Вывод русского языка
Ввожу #include &lt;locale.h&gt; setlocale(LC_ALL,&quot;.1251&quot;); или setlocale(LC_ALL,&quot;rus&quot;); На Windows 7 работает, на Windows Хр...

Неправильный вывод в консоль
Добрый день! я написал программу для транспонирования матрицы. При вводе квадратной матрицы, программа работает, а при вводе матрицы,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
36
Ответ Создать тему
Новые блоги и статьи
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Оказывается, Unreal Engine позволяет качество на порядки выше, чем было в Lineedge
Etyuhibosecyu 05.07.2026
Жаль, конечно, что я не узнал об этом, пока Lineedge существовала, а то бы Noname2331 написал, что волки превращаются в пиксельную кашу, а я бы его попросил скачать какую-нибудь бриллиантовую или Pro. . .
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru