Меню
Категории
Вывод русских букв в консольных приложениях на C++
19 февраля, 2008 Программинг

Компилируя консольные приложения на славном языке программирования C++ постоянно сталкиваешься с проблемой кодировок. Русские буквы выводятся каракулями, а с английскими все в порядке. Дело в кодировках. В консоли Windows используется кодировка OEM. А в самой ОС Windows – ANSI кодировка.

Для избежания проблем с выводом русских букв в консоль мы будем пользоваться функцией CharToOem.

Функция CharToOem преобразует строку в набор символов ОЕМ. Эта функция противоположна функции AnsiToOem.

BOOL CharToOem (
LPCTSTR lpszSrc , // указатель на преобразуемую строку
LPSTR lpszDst // указатель на буфер для преобразованной строки
);

Параметры

lpszSrc – указывает на завершающуюся нулем преобразуемую строку.
lpszDst – указывает на буфер для преобразованной строки. Если CharToOem используется как ANSI -функция, то можно установить параметр lpszDst на тот же адрес, что и параметр lpszSrc . Это не может быть осуществлено в случае использования CharToOem как Unicode -функции.

Пример ниже показывает вывод русских букв в консоль. Для этого нужно подключить библиотеку “windows.h”. Функция CharToOem выполняет преобразование.

Преобразование нужно проводить только для вывода на экран, для вывода в файл или внутренней работы с переменными это делать не нужно.

#include <windows.h> //нужна для функции CharToOem

void main()
{

char buf[10];
char str[10]=”qwertyuiop”;
CharToOem(str, buf); //преобразование
cout<<buf<<endl;
delete[] buf; //Больше нам массив buf не нужен.
}

Вот и всё.

42 комментария
  1. этого не надо (delete[] buf;) так как не было динамического выделения памяти
    и еще надо подключить iostream.h для cout
    вот рабочий код

    #include
    #include
    #include
    using namespace std;

    int main(int argc, char* argv[])
    {
    char str[10] = “мама мыла”;
    char buf[10];
    CharToOem(str, buf);
    cout << buf << endl;
    getch();
    return 0;
    }

  2. пля, библиотеки, не отобразило
    вот они
    windows.h для функции CharToOem
    iostream.h для вывода cout
    conio.h для задержки экрана getch()

  3. А как сделать так чтоб он весь русский текст выводил нормально? а то если много русских строчек, неудобно делать перевод для каждой или функцию, которая их транслирует.
    PS вместо getch() удобнее пользоваться system(“pause”); он без библиотек идет

  4. #include
    #include
    #include
    using namespace std;
    int main(int nNumberofArgs, char* pszArgs[])
    {

    char buf[256]; // размер буфера зависит от размера исходной строки
    ::CharToOem( “Привет, Мир!\n”, buf );
    cout << buf << endl;

    system (“PAUSE”);
    return 0;
    }

  5. #include
    #include
    #include

    int main(int nNumberofArgs, char* pszArgs[])
    {

    char buf[256]; // размер буфера зависит от размера исходной строки
    ::CharToOem( “Привет, Мир!\n”, buf );
    cout << buf << endl;

    system (“PAUSE”);
    return 0;
    }
    вот что вывела консоль:
    Привет, Мир!

    Для продолжения нажмите любую клавишу . . .
    Press any key to continue

  6. если нужна русская строчка, причем ты ее собрался выводить как константу, достаточно воспользоваться функцией system:

    void main()
    {
    system(“echo”);
    system(“echo “);
    }

  7. Для удобство можно все это загнать в препроцессор и через define сократить до одной команды.

    include
    include
    using namespace std;
    define cyrOut(_string_) CharToOem(_string_,szStr);\
    cout << szStr

    char szStr[512];
    int main()
    {
    cyrOut(“Хэллоу Уорлд”);
    system(“Pause”);
    return 0;
    }

    перед include и define ставим, естественно #

  8. Ахаха… Движом форума прочитал названия библиотек, как хтмл-теги. Ну вы поняли – библиотеки – iostream и windows.h

  9. Error 1 error C2664: ‘CharToOemW’ : cannot convert parameter 1 from ‘const char [14]’ to ‘LPCWSTR’ – вот какая красота выходит в Visual Studio 2005, и как с ней бороться???

  10. Все хотел спросить – почему выбрали именно домен http://www.makak.ru?

  11. cyrOut(”Хэллоу Уорлд”);
    system(”Pause”);

    с такими кавычками компилятор выдал 17 ошибок)))

    ставьте обычные ” “

  12. Кавычки преобразовал движок сайта =) я ставил обычные.

  13. Error 1 error C2664: ‘CharToOemW’ : cannot convert parameter 1 from ‘const char [14]’ to ‘LPCWSTR’ – вот какая красота выходит в Visual Studio 2005, и как с ней бороться???

    это ругань на то что юзается уникод версия функции, о чем говорит W в конце.
    правится: Проект – Свойства – General – Set Character = Multy-Byte

  14. я тут мимоходом

    Чтобы во всей программе спокойно использовать русские буквы, достаточно один раз (где-нибудь в начале) прописать:
    [code]#include

    setlocale( LC_ALL, “Russian” );[/code]

  15. я тут мимоходом

    Мда, движок сайта жжот… BB коды не принимает.
    Нужно:
    #include &ltlocale&gt

  16. я тут мимоходом

    Тьфу…

    Ну вы поняли :)

  17. Для вывода русских букв в консоли Visual C++, достаточно в тело программы (можно в main) записать следующее:

    setlocale(0, “”);

  18. Ну вы блин жжоте.

    setlocale(LC_ALL,”Russian”);

    и всё. В первую очередь надо у MSDN спрашивать.
    https://msdn.microsoft.com/en-us/library/x99tb11d.aspx

  19. Спасибо большое все работает

  20. Большое СПАСИБО. Я раньше решал проблему по-другому. Сначала я вывел в консоль 255 символов и увидел среди них русские. Таблица символов была “не на своём месте” и к тому же с разрывом. Я сделал соответствующие корректировки:

    #include “iostream”
    #include “string”
    using namespace std;
    void WriteRussianString(string stringForWrite);
    main() {
    WriteRussianString(“Привет, Мир!!!”);
    getchar();
    return 0;
    }

    void WriteRussianString(string stringForWrite) {
    // коды начала и конца первого отрезка русского алфавита
    unsigned long beginOtrezok_1_RusABC = 0x0FFFFFFC0;
    unsigned long endOtrezok_1_RusABC = 0x0FFFFFFEF;
    // коды начала и конца второго отрезка русского алфавита
    unsigned long beginOtrezok_2_RusABC = 0x0FFFFFFF0;
    unsigned long endOtrezok_2_RusABC = 0x0FFFFFFFF;

    // переменная для временного хранения символов
    char charTemp;

    // порядковый номер символа в принятой строке
    int count_char = 0;

    charTemp = stringForWrite[count_char];
    // перебираем символы в входной строке, корректируем их коды и
    // и выводим эти символы
    while (charTemp != ”) {
    count_char++;

    // коррекция символов из первого и второго интервала русских символов
    char charForPrint;
    unsigned long codeCharTemp;
    codeCharTemp = (unsigned long)charTemp;
    if ((beginOtrezok_1_RusABC <= codeCharTemp ) && (codeCharTemp <= endOtrezok_1_RusABC)) {
    charForPrint = char(codeCharTemp-64);
    cout << charForPrint;
    }
    else {
    if ((beginOtrezok_2_RusABC <= codeCharTemp ) && (codeCharTemp <= endOtrezok_2_RusABC)) {
    charForPrint = char(codeCharTemp-16);
    cout << charForPrint;
    }
    else {
    cout << charTemp;
    }
    }
    charTemp = stringForWrite[count_char];
    }
    cout << endl;
    }

  21. Пользуюсь кодом по совету Марата. Марат СПАСИБО!!!

  22. для вывода русских символов можно пользоваться этой функцией:

    void print_rus(const char c[])
    {
    char ch;
    for (int i=0;c[i]!=0;i++)
    {
    ch=c[i];
    if ((ch>=’А’)&(ch=’р’)&(ch<='я')) ch-=16;
    else if (ch=='Ё') ch+=72;
    else if (ch=='ё') ch+=57;
    else if (ch=='№') ch+=67;
    cout<<ch;
    }
    }

    Воплощение её в основной программе:
    void main()
    {
    print_rus ("Сообщение на русском языке");
    }

  23. Прошу прощения, ошибся.

    void print_rus(const char c[])
    {
    char ch;
    for (int i=0;c[i]!=0;i++)
    {
    ch=c[i];
    if ((ch>=’А’)&(ch=’р’)&(ch<='я')) ch-=16;
    else if (ch=='Ё') ch+=72;
    else if (ch=='ё') ch+=57;
    else if (ch=='№') ch+=67;
    cout<<ch;
    }
    }

  24. void print_rus(const char c[])
    {
    char ch;
    for (int i=0;c[i]!=0;i++)
    {
    ch=c[i];
    if ((ch>=’А’)&(ch=’р’)&(ch<='я')) ch-=16;
    else if (ch=='Ё') ch+=72;
    else if (ch=='ё') ch+=57;
    else if (ch=='№') ch+=67;
    cout<<ch;
    }
    }

  25. #include
    #include
    #include
    using namespace std;
    char* Rus(const char* text);
    int main() {
    cout << Rus("\nпривет мир\n");
    cout << Rus("бла бла бла\n");
    cout << Rus("пока всем\n");
    getch();
    return 0;
    }
    // ф-ция русификации
    char buf[256]; // за пределами функции
    char* Rus(const char* text)
    {

    CharToOem(text, buf);
    return buf;
    }

  26. инклуды стандартные:
    iostream
    windows.h
    conio.h

  27. САМЫЙ ЛЕГКИЙ И ЭФФЕКТИВНЫЙ МЕТОД

    Запускаем консоль, щелкаем на заголовке окна и выбираем свойства.
    В свойствах на закладке Шрифт ставим шрифт Lucida Console и жмем
    ОК. Чтобы вид консули не сильно отличился от обычной, ставим галочку
    жирный и потом жмем ОК.

    Далее набираем в консоли ChCp 1251, в ответ получаем Текущая
    кодовая страница: 1251. Теперь запускаем С++ программу и
    убеждаемся, что все работает. При желании можно написать bat-файл
    куда вставить ChCp 1251 и создать для этого файла ярлык, в
    свойствах которого прописать шрифт Lucida Console.

    Допустим в коммандной строке шрифт ставили Lucida Console.
    То можно данный скрипт сохранить в BAT файле, и насладится.

    @echo off
    chcp 1251
    cls
    cmd /k C:\Welcome.exe

    На мой взгляд данный метод самый простой и самый эффективный, но
    о ней проктически не пишут. Работает с Visual Studio, C++BuilderX,
    wxDev-C++ и другимы компиляторамы.

  28. Может я не в тему но если в визуал студио открыть исходный файл в кодировке дос а потом скомпилировать то итак всё нормально отображается потом в консольке

  29. include \
    include \

    int main()
    {
    setlocale(0,””);
    std::cout<<"Все будет по-русски"<<std::endl;
    return 0;
    }

  30. iostream и locale в инклуде

Добавить комментарий




*