Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/201: Рейтинг темы: голосов - 201, средняя оценка - 4.78
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1

Русский текст без танцев с бубнами

11.11.2011, 22:39. Показов 38820. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.

Решил раз и навсегда понять, как выводить русские буквы на консоль без всяких танцев с system("chcp ...") или SetConsoleCP. Интересует вариант, при котором исходник неизменно хранится в UTF-8, и компилируется на разных платформах. В частности интересуют *nix, cygwin, mingw. Пробовал такой вариант:

Вариант с std::wstring
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
 
int main( )
{
    std::wcout << L'>';
 
    std::wstring input;
    getline( std::wcin, input );
 
    std::wcout << input;
 
    input = L",Здравствуй, мир!";
 
    std::wcout << L'\n' << input;
 
    return 0;
}
Цитата Сообщение от MinGW (gcc 4.6.1)
>Привет, мир!
Привет, мир!
,
Цитата Сообщение от Cygwin (gcc 4.5.3)
>здравствуй, мир!

,
(оба сожрали строки, начиная с первой русской буквы)


И такой:

Вариант с std::string
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
 
int main( )
{
    std::cout << '>';
 
    std::string input;
    getline( std::cin, input );
 
    std::cout << input;
 
    input = ",Здравствуй, мир!";
 
    std::cout << '\n' << input;
 
    return 0;
}
Цитата Сообщение от MinGW (gcc 4.6.1)
>здравствуй, мир!
здравствуй, мир!
,╨Ч╨┤╤А╨░╨▓╤Б╤В╨▓╤Г╨╣, ╨╝╨╕╤А!
(что вполне ожидаемо)
Цитата Сообщение от Cygwin (gcc 4.5.3)
>здравствуй, мир!
здравствуй, мир!
,Здравствуй, мир!
(опа!)


И тут мне стало интересно, почему они сожрали std::wstring, начиная с первой встреченной русской буквы, и почему вдруг на cygwin заработал вариант с std::string, хотя std::wstring всё так же успешно сжирается? И самое главное: как сделать так, чтобы и std::wstring, и std::string корректно работали с русскими символами под всеми платформами без перекодирования исходника в нативную кодировку системы.

С локалями тоже не удалось:
std::locale

C++
1
2
3
4
// валится уже на конструкторе std::locale
std::locale( "rus_rus.1251" );
std::locale( "Russian_Russia.1251" );
// и подобные
оба (mingw и cygwin) выдают следующее:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
Точно так же cygwin ругается на
C++
1
std::locale("");
MingW это кушает, но продолжает уверенный и наглый вывод в левой кодировке.
у mingw


В общем, я несколько в замешательстве. Стандартная библиотека C++ (и Си по возможности) предоставляет средства для решения подобных проблем?

Добавлено через 16 минут

Не по теме:

Возможно, стоило разместить эту тему в ветке "Кроссплатформенная разработка"?

0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.11.2011, 22:39
Ответы с готовыми решениями:

Xcode , С++ и русский язык: как вывести в файл русский текст без сбитой кодировки?
Как сделать так, чтобы после некоторых манипуляций в файл выводился русский текст без сбитой кодировки?

пдскажите функцию которая выводит русский текст на экран и его заголовочный файл с++ но не system ( " echo текст " );
пдскажите функцию которая выводит русский текст на экран и его заголовочный файл с++ но не system ( &quot; echo текст &quot; );

Русский текст
Помогите сделать на русском в консоли ввод и вывод! Пишу в консоли русскими а выдаёт иероглифы! #include &lt;iostream&gt; ...

22
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.11.2011, 22:44
И ещё вариантик от меня - перегрузка оператора вывода
перегрузка operator<<(
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
#include <iostream>
using namespace std;
 
//Руссификация
ostream& operator<<(ostream &stream,char* s){
    for(char* ps=s; *ps; ps++){
        if(*ps=='ё')
            stream<<char(241);
        else if(*ps=='Ё')
            stream<<char(240);
        else if(*ps>=-64 && *ps<=-17)           
            stream<<char(*ps+64+128);
        else if(*ps<0)
            stream<<char(*ps+64+176);
        else
            stream<<*ps;
    }
    return stream;
}
 
int main()
{
    cout<<"Руссификация без танцев с бубнами;)\n";
    system("pause");
    return 0;
}
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 22:50  [ТС]
-=ЮрА=-, спасибо, конечно, но это тоже бубен, только самодельный.

Вот почему:
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
if(*ps=='ё') stream<<char(241);
А если в нативной кодировке системы 241-й символ будет не 'ё'? (есть ведь ещё UTF-8, KOI8R, DOS-886 и прочие).

Всё равно спасибо.
0
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
11.11.2011, 23:04
В windows( Visual Studio 2008 ) ни вариант с wstring, ни вариант с string не работают правильно.
0
79 / 34 / 6
Регистрация: 11.11.2010
Сообщений: 496
12.11.2011, 00:39
А такой вариант?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream.h> 
 
char bufRus[256];//объявляем глобальную переменную
 
char* RUS(const char*text) //функция поддержки русского языка
{
CharToOem(text,bufRus);
return bufRus;
}
 
int main()
{
 
cout<<RUS("Привет!");
 
}
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 00:41  [ТС]
maest, CharToOem - функция WinAPI. И это тоже бубен.

Цитата Сообщение от talis Посмотреть сообщение
В частности интересуют *nix, cygwin, mingw. <...> Стандартная библиотека C++ (и Си по возможности) предоставляет средства для решения подобных проблем?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,977
12.11.2011, 01:07
talis, в CygWin только не отработало
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <wchar.h>
#include <stdio.h>
#include <locale.h>
 
int main(void){
    wchar_t buf[BUFSIZ];
    
    setlocale(LC_ALL, "ru_RU.UTF-8");
    
    printf("%S: ", L"Имя");
    if ( scanf("%S", buf) != 1 ){
        fprintf(stderr, "%S\n", L"Ошибко!");
        return 1;
    }
    
    printf("%S %S\n", L"Здравствуй, дорогой товарищ", buf);
    
    return 0;
}
Проверял в винде (cl и MinGW gcc), в CygWin (с этим не задалось), в MacOS X и Debian linux
2
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 01:24  [ТС]
easybudda, хм, MinGW не отработал. Не вывел русские символы, записанные в исходнике, зато обработал введённую строку.
: талис
талис
Cygwin - наоборот. Корректно вывел символы из исходника, но отказался обрабатывать введённую строку:
$ ./main.exe
Имя: талис
Ошибко!
Файл один и тот же, в UTF-8 (без BOM).

Не по теме:

Тихо шифером шурша, крыша едет не спеша...

0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,977
12.11.2011, 01:33
talis, дома нет винды, на работе пробовал - вроде работало... Странно всё... Ну в никсах за то работает
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 02:00  [ТС]
easybudda, так толку-то мне с никсов, если программа для винды делается? За спиной стоит машинка с убунтой и freebsd (под виртуалкой в убунте), завтра утром попробую. Хотя вопрос как раз таки в универсальном решении. Ну не может же быть такого, чтобы все эти локали, кодировки и wide-charы были введены в стандарт от балды и не были отлажены. Должен быть способ заставить это работать как надо.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,977
12.11.2011, 02:27
Цитата Сообщение от talis Посмотреть сообщение
Ну не может же быть такого, чтобы все эти локали, кодировки и wide-charы были введены в стандарт от балды и не были отлажены.
Ну мелкомягким разработчикам, видимо, просто забить на это дело. Я другой такой оси не знаю, чтобы русский текст аж в трёх кодировках представлялся, при чём сразу. А попробуйте вместо "ru_RU.UTF-8" написать "ru_RU.CP866" - просто интересно, будет оно так в виндовой консоли работать, не?..
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 02:30  [ТС]
easybudda, то же самое. У меня давно складывается впечатление, что под виндой setlocale и плюсовый аналог нагло игнорируют кодировку, и применяют только форматы чисел с плавающей точкой, даты/времени и прочего.
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
12.11.2011, 04:25
Цитата Сообщение от easybudda Посмотреть сообщение
Я другой такой оси не знаю
где так вольно дишит человек
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 12:27  [ТС]
easybudda, под убунтой работает и ваш вариант с wchar_t, и аналогичный с char, причём последний даже без setlocale ("ru_RU.UTF-8" - это системная локаль). Аналогичный код на плюсах с широкими символами требует std::locale::global( std::locale( "ru_RU.UTF-8" ) ), причём имя локали такое с точность до регистра символа, разве что чёрточку в UTF-8 можно опустить, а плюсовый код с обычными символами так же работает без ручной установки локали.

Точно такое же имя локали под виндой валит конструктор std::locale.

В общем, вопросов опять больше чем ответов. Главный вопрос - какого ... оно так (не) работает? И ещё: почему в никсе вариант с char подхватывает системную локаль, а wchar_t её нужно выставлять руками? Что будет, если системная кодировка окажется, скажем, KOI8R?
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
15.11.2011, 20:49
talis, попробуйте system("chcp 1251");
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
 
int main()
{
    system("chcp 1251");//Установка кодовой страницы
    cout<<"Руссификация без танцев с бубнами;)\n";
    system("pause");
    return 0;
}
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
16.11.2011, 17:11  [ТС]
Цитата Сообщение от talis Посмотреть сообщение
исходник неизменно хранится в UTF-8
поэтому все строки в исполняемом файле тоже UTF. Ваш вариант в этих условиях выводит:

Текущая кодовая страница: 1251
Р*уссификация без танцев СЃ бубнами

Кроме того:

Цитата Сообщение от talis Посмотреть сообщение
как выводить русские буквы на консоль без всяких танцев с system("chcp ...")
Всё равно спасибо за участие
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
16.11.2011, 17:17
talis, так вроде дело то в кодировке виндовой консоли, разве нет? Зачем исходники-то мучить
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
16.11.2011, 17:26  [ТС]
fasked, я же и хочу не мучить исходники. Ищу универсальное бескостыльное решение для отображения русского текста на разных платформах без изменения исходника. Как он был в UTF-8, так он в нём везде и гуляет.

В Юрином варианте:

C++
1
2
        system("chcp 65001");//Установка кодовой страницы
        cout << "Руссификация без танцев с бубнами;)\n";
Ничего не выводит

C++
1
2
        system("chcp 65000");//Установка кодовой страницы
        cout << "Руссификация без танцев с бубнами;)\n";
Выводит другие кракозябры:
Текущая кодовая страница: 65000
Ð*уссификация без танцев с бубнами
Хотя файл в UTF-8, => 65001 должна была сработать.
0
16.11.2011, 17:37

Не по теме:

talis, я Вас не обманывал, правда только теперь вник в ваше задание, сейчас попробую кое что вам отыскать, посмотрите пока в сторону MulyByteToWideChar и ей обратную...

Миниатюры
Русский текст без танцев с бубнами  
0
16.11.2011, 17:39

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
MulyByteToWideChar
это уже бубен

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.11.2011, 17:39
Помогаю со студенческими работами здесь

Русский текст вывод
братцы есть быдло код: #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;stdlib.h&gt; #include &lt;vector&gt; #include&lt;locale.h&gt; ...

string русский текст
Привет.. вобщем тут по примеру делал что-то типа телефонной книги(да практически все списал), так вот, не работает, но по отладке видно,...

Вывести русский текст
Помогите пожалуйста, как вывести в консоль не просто русский текст, а именно вывести текст из переменной?

Не печатает русский текст
Здравствуйте, у меня возникла проблема, я не могу печать русский текст.Вместо текста, непонятные ероглифы. Использую я C++ CodeBlocks. ...

Русский текст в консоли
Мне нужно чтобы когда я напишу свое имя по русски и оно выводиться по русски у меня не выходит так выводит разные &quot;крякозавры&quot;, ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определенном условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru