Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 130, средняя оценка - 4.98
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 22:39     Русский текст без танцев с бубнами #1
Доброго времени суток.

Решил раз и навсегда понять, как выводить русские буквы на консоль без всяких танцев с 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 минут

Не по теме:

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

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
11.11.2011, 22:44     Русский текст без танцев с бубнами #2
И ещё вариантик от меня - перегрузка оператора вывода
перегрузка 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;
}
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 22:50  [ТС]     Русский текст без танцев с бубнами #3
-=ЮрА=-, спасибо, конечно, но это тоже бубен, только самодельный.

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

Всё равно спасибо.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
11.11.2011, 23:04     Русский текст без танцев с бубнами #4
В windows( Visual Studio 2008 ) ни вариант с wstring, ни вариант с string не работают правильно.
maest
78 / 33 / 2
Регистрация: 11.11.2010
Сообщений: 472
12.11.2011, 00:39     Русский текст без танцев с бубнами #5
А такой вариант?

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("Привет!");
 
}
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 00:41  [ТС]     Русский текст без танцев с бубнами #6
maest, CharToOem - функция WinAPI. И это тоже бубен.

Цитата Сообщение от talis Посмотреть сообщение
В частности интересуют *nix, cygwin, mingw. <...> Стандартная библиотека C++ (и Си по возможности) предоставляет средства для решения подобных проблем?
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
12.11.2011, 01:07     Русский текст без танцев с бубнами #7
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
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 01:24  [ТС]     Русский текст без танцев с бубнами #8
easybudda, хм, MinGW не отработал. Не вывел русские символы, записанные в исходнике, зато обработал введённую строку.
: талис
талис
Cygwin - наоборот. Корректно вывел символы из исходника, но отказался обрабатывать введённую строку:
$ ./main.exe
Имя: талис
Ошибко!
Файл один и тот же, в UTF-8 (без BOM).

Не по теме:

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

easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
12.11.2011, 01:33     Русский текст без танцев с бубнами #9
talis, дома нет винды, на работе пробовал - вроде работало... Странно всё... Ну в никсах за то работает
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 02:00  [ТС]     Русский текст без танцев с бубнами #10
easybudda, так толку-то мне с никсов, если программа для винды делается? За спиной стоит машинка с убунтой и freebsd (под виртуалкой в убунте), завтра утром попробую. Хотя вопрос как раз таки в универсальном решении. Ну не может же быть такого, чтобы все эти локали, кодировки и wide-charы были введены в стандарт от балды и не были отлажены. Должен быть способ заставить это работать как надо.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9371 / 5421 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
12.11.2011, 02:27     Русский текст без танцев с бубнами #11
Цитата Сообщение от talis Посмотреть сообщение
Ну не может же быть такого, чтобы все эти локали, кодировки и wide-charы были введены в стандарт от балды и не были отлажены.
Ну мелкомягким разработчикам, видимо, просто забить на это дело. Я другой такой оси не знаю, чтобы русский текст аж в трёх кодировках представлялся, при чём сразу. А попробуйте вместо "ru_RU.UTF-8" написать "ru_RU.CP866" - просто интересно, будет оно так в виндовой консоли работать, не?..
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 02:30  [ТС]     Русский текст без танцев с бубнами #12
easybudda, то же самое. У меня давно складывается впечатление, что под виндой setlocale и плюсовый аналог нагло игнорируют кодировку, и применяют только форматы чисел с плавающей точкой, даты/времени и прочего.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
12.11.2011, 04:25     Русский текст без танцев с бубнами #13
Цитата Сообщение от easybudda Посмотреть сообщение
Я другой такой оси не знаю
где так вольно дишит человек
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
12.11.2011, 12:27  [ТС]     Русский текст без танцев с бубнами #14
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?
-=ЮрА=-
Заблокирован
Автор FAQ
15.11.2011, 20:49     Русский текст без танцев с бубнами #15
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;
}
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
16.11.2011, 17:11  [ТС]     Русский текст без танцев с бубнами #16
Цитата Сообщение от talis Посмотреть сообщение
исходник неизменно хранится в UTF-8
поэтому все строки в исполняемом файле тоже UTF. Ваш вариант в этих условиях выводит:

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

Кроме того:

Цитата Сообщение от talis Посмотреть сообщение
как выводить русские буквы на консоль без всяких танцев с system("chcp ...")
Всё равно спасибо за участие
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
16.11.2011, 17:17     Русский текст без танцев с бубнами #17
talis, так вроде дело то в кодировке виндовой консоли, разве нет? Зачем исходники-то мучить
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
16.11.2011, 17:26  [ТС]     Русский текст без танцев с бубнами #18
fasked, я же и хочу не мучить исходники. Ищу универсальное бескостыльное решение для отображения русского текста на разных платформах без изменения исходника. Как он был в UTF-8, так он в нём везде и гуляет.

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

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

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

Не по теме:

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

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.11.2011, 17:39     Русский текст без танцев с бубнами
Еще ссылки по теме:

C++ Русский текст вывод
C++ Русский текст в консоли
Русский текст в консоли C++

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

Или воспользуйтесь поиском по форуму:
Jupiter
16.11.2011, 17:39     Русский текст без танцев с бубнами
  #20

Не по теме:

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

Yandex
Объявления
16.11.2011, 17:39     Русский текст без танцев с бубнами
Ответ Создать тему
Опции темы

Текущее время: 02:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru