Русские буквы в консольном приложении.
От: Аноним  
Дата: 29.06.08 13:55
Оценка:
Доброго времени суток!

Следующий код:
#include <iostream>
#include <locale>

int main()
{
    std::locale::global(std::locale("rus"));

    std::cout << "абвгд" << std::endl;
    return 0;
}

приводит в компиляторе MinGW GCC 3.4.5. к ошибке
This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
Что в этом коде не так? Как сделать, чтобы печатались русские буквы?
Re: Русские буквы в консольном приложении.
От: Аноним  
Дата: 29.06.08 14:23
Оценка: 18 (4)
Здравствуйте, Аноним, Вы писали:

А>Доброго времени суток!


А>Следующий код:

А>
А>#include <iostream>
А>#include <locale>

А>int main()
А>{
А>    std::locale::global(std::locale("rus"));

А>    std::cout << "абвгд" << std::endl;
А>    return 0;
А>}
А>

А>приводит в компиляторе MinGW GCC 3.4.5. к ошибке
А>This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
А>Что в этом коде не так? Как сделать, чтобы печатались русские буквы?


Дело в том, что в MinGW (по крайней мере, в используемой Вами версии) не определены локали, кроме классической C (ну, ещё POSIX, но это разве не одно и то же? ). Выход — определить свою codecvt:

// Не забудьте подключить <windows.h> для OemToCharBuff и CharToOemBuff!
class LocaleIBM866 : public std::codecvt <char, char, std::mbstate_t> {
  public:
    explicit LocaleIBM866 ( size_t r = 0 ) : std::codecvt <char, char, std::mbstate_t> ( r ) {}

  protected:
    result do_in ( state_type&, const char* from, const char* from_end, const char*& from_next, char* to, char*, char*& to_next ) const {
        const int size = from_end - from;
        ::OemToCharBuff ( from, to, size );

        from_next = from + size;
        to_next = to + size ;

        return ok;
    }

    result do_out ( state_type&, const char* from, const char* from_end, const char*& from_next, char* to, char*, char*& to_next ) const {
        const int size = from_end - from;
        ::CharToOemBuff ( from, to, size );

        from_next = from + size;
        to_next = to + size ;

        return ok;
    }

    result do_unshift ( state_type&, char*, char*, char*& ) const { return ok; }
    int do_encoding () const throw () { return 1; }
    bool do_always_noconv () const throw () { return false; }

    int do_length ( state_type& state, const char* from, const char* from_end, size_t max ) const {
      return std::codecvt <char, char, std::mbstate_t>::do_length ( state, from, from_end, max );
    }

    int do_max_length () const throw () {
      return std::codecvt <char, char, std::mbstate_t>::do_max_length ();
    }
};


Насчёт выделенного: правильнее, ИМХО, отсчитывать from_next от from_end, но с from_end у меня вариант на MinGW падал с исключением

Теперь, чтобы "включить" нашу локаль, в main пишем:

    std::locale rus ( std::locale (), new LocaleIBM866 () );
    std::ios_base::sync_with_stdio ( false );
    std::cout.imbue ( rus );
    std::cin.imbue ( rus );


Думаю, не стоит упоминать, что imbue нужно делать только для нужных потоков.
Выделенное жирным — особенность реализации локалей под MinGW (может, и в gcc в целом — я не в курсе). Пока не выключите синхронизацию с stdio — установленная локаль не будет работать

Теперь Ваша функция main будет выглядеть так:

int main()
{
        std::locale rus ( std::locale (), new LocaleIBM866 () );
        std::ios_base::sync_with_stdio ( false );
        std::cout.imbue ( rus );
        std::cin.imbue ( rus );

    std::cout << "абвгд" << std::endl;
    return 0;
}


P.S. А программа завершается unusual way из-за того, что при код не находит локали с именем "rus" и кидает соответствующее исключение.
locale mingw
Re: Русские буквы в консольном приложении.
От: kurt84 Сингапур  
Дата: 30.06.08 05:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Доброго времени суток!


А>Следующий код:

А>
А>#include <iostream>
А>#include <locale>

А>int main()
А>{
А>    std::locale::global(std::locale("rus"));

А>    std::cout << "абвгд" << std::endl;
А>    return 0;
А>}
А>

А>приводит в компиляторе MinGW GCC 3.4.5. к ошибке
А>This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
А>Что в этом коде не так? Как сделать, чтобы печатались русские буквы?

А std::wcout не спасет?
Re[2]: Русские буквы в консольном приложении.
От: serg baburin Россия  
Дата: 30.06.08 07:00
Оценка:
Здравствуйте, kurt84, Вы писали:

K>А std::wcout не спасет?

Не спасёт — Re: mingw и wcout
Автор: Mazay
Дата: 21.03.08
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.