ПрограммированиеFAQОбщее

Как вывести в консоль русские буквы?

Подключаем locale.h, в коде пишем setlocale(LC_ALL, "rus");

#include <stdio.h>
#include <locale.h>

int main()
{
  setlocale(LC_ALL, "rus");

  printf("%s", "Привет, мир!");

  return 0;
}

Cредствами с++:

#include <iostream>
#include <locale>

int main()
{
    std::locale rus("rus_rus.866");

    std::wcout.imbue(rus);

    std::wcout << L"Привет, мир!!!";

    return 0;
}

Для Delphi

function Rus(mes: string):string;
// В ANSI русские буквы кодируются числами от 192 до 255,
// в ASCII - от 128 до 175 (А..Яа..п) и от 224 до 239 (р..я).
  var
    i: integer; // номер обрабатываемого символа
  begin
    SetLength(Result,length(mes));
    for i:=1 to length(mes) do
      case mes[i] of
        'А'..'п' :Result[i] := Chr(Ord(mes[i]) - 64);
        'р'..'я' :Result[i] := Chr (Ord(mes [i] ) -16);
        else Result[i]:=mes[i];
      end;
  end;

7 января 2008 (Обновление: 28 фев 2008)

Комментарии [19]

Страницы: 1 2 Следующая »
#1
16:34, 12 июня 2009

Что за <local.h>? Где берется?
Я всегда юзал system("chcp 1251") из "windows.h" еслече(-:

#2
16:57, 12 июня 2009

iGod
> Я всегда юзал system("cp 1251") из "windows.h" еслече(-:
cp: missing destination file
Try `cp --help' for more information.

#3
17:31, 12 июня 2009

X512
Прости, имелл ввиду "chcp 1251"
change codepage

Давно на плюсах не писал

#4
17:41, 12 июня 2009

iGod
Код

#include <stdio.h>
#include <windows.h>

int main()
{
    system("chcp 1251");
    printf("%s\n","Русский текст");
    return 0;
}

выдаёт
i.png | Как вывести в консоль русские буквы?.

#5
17:50, 12 июня 2009

iGod
>Что за <local.h>? Где берется?
<locale.h>

X512
>выдаёт
Там написано.
Текущая кодовая страница: 1252
Русский текст

#6
17:51, 12 июня 2009

X512
Озадачил...

#7
19:28, 23 июня 2009

NightmareZ:
Выводи через эту функцию:

__forceinline PSTR ANSItoASCII(PSTR pStr)
{
  for(PUINT8 p = (PUINT8)pStr; *p; ++p)
    if (*p >= 192)
      *p <= 239 ? *p-=64 : *p-=16;
  return pStr;
}
#8
21:04, 23 июня 2009

NightmareZ
> Как вывести в консоль русские буквы?
Что за безумие?? Когда я это писал? O_O

#9
8:54, 24 июня 2009

известная ссылка, но все же:
http://www.rsdn.ru/article/qna/ui/concp.xml

ну и сам я когда-то вот этим пользовался (извините за длинный текст):

console.h

//console.h
#pragma once
#include <windows.h>
#include <string.h>
#include <wincon.h>

//создание цвета/фона
#define RGBI(fr,fg,fb,fi,br,bg,bb,bi)      \
    (fr == 1 ? FOREGROUND_RED       : 0) | \
    (fg == 1 ? FOREGROUND_GREEN     : 0) | \
    (fb == 1 ? FOREGROUND_BLUE      : 0) | \
    (fi == 1 ? FOREGROUND_INTENSITY : 0) | \
    (br == 1 ? BACKGROUND_RED       : 0) | \
    (bg == 1 ? BACKGROUND_GREEN     : 0) | \
    (bb == 1 ? BACKGROUND_BLUE      : 0) | \
    (bi == 1 ? BACKGROUND_INTENSITY : 0)

//часто используемые цвета
const WORD attrWhiteBlack = RGBI(1,1,1,1,0,0,0,0);

//событие ввода
struct Event
{
    enum Type
    {
        KeyUp,   //отжатие
        KeyDown, //нажатие
        Nothing, //ничего
        Timer    //таймер
    } type;   //тип
    int code; //код клавиши
    char ch;  //символ
    int id;   //номер таймера
};

//функции
void  Init         (int wd, int hg, const char *title);
void  Done         ();
void  SetTitle     (const char *title);
void  PutInt       (int x, int y, int num, WORD at = attrWhiteBlack);
void  PutChar      (int x, int y, const char *str, WORD at = attrWhiteBlack);
void  PutAttr      (int x, int y, WORD at, int len = 1);
void  SetSize      (int wd, int hg);
void  GetSize      (int *wd, int *hg);
void  SetCurPos    (int x, int y);
void  GetCurPos    (int *x, int *y);
void  ShowCur      (bool show);
void  Clear        (WORD at = attrWhiteBlack);
char  GetChar      (int x, int y);
WORD  GetAttr      (int x, int y);
void  FillRect     (int x, int y, int wd, int hg, char ch, WORD at = attrWhiteBlack);
void  Swap         ();
bool  IsQueueEmpty ();
Event GetNextEvent ();

console.cpp

//console.cpp
#include "console.h"
#include <mbstring.h>
#include <locale.h>
#include <stdio.h>

static HANDLE     con    = INVALID_HANDLE_VALUE;
static int        width  = 0;
static int        height = 0;
static UINT       oldcp  = 0;
static CHAR_INFO *buffer = 0;

void Init (int wd, int hg, const char *title)
{
    if (con != INVALID_HANDLE_VALUE)
        Done();

    //настроим кодовую страницу
    oldcp = GetConsoleOutputCP();
    SetConsoleOutputCP(1251);
    setlocale(LC_ALL,"Russian");

    //создадим видеобуфер
    con = CreateConsoleScreenBuffer
          (
             GENERIC_READ | GENERIC_WRITE,
             0,
             NULL,
             CONSOLE_TEXTMODE_BUFFER,
             NULL
          );

    //установим заголовок
    SetTitle(title);

    //установим размеры
    SetSize(wd,hg);
}

void Done ()
{   
    SetConsoleOutputCP(oldcp);

    if (con != INVALID_HANDLE_VALUE)
    {
        CloseHandle(con);
        con = INVALID_HANDLE_VALUE;
    }

    if (buffer)
    {
        delete[] buffer;
        buffer = 0;
    }
}

void SetTitle (const char *title)
{
    static char str[1024];
    CharToOemA(title,str);
    SetConsoleTitleA(str);
}

void PutInt (int x, int y, int num, WORD at)
{
    static char str[1024];
    _snprintf_s(str,1024,"%d",num);
    PutChar(x,y,str,at);
}

void PutChar (int x, int y, const char *str, WORD at)
{
    if (con == INVALID_HANDLE_VALUE || buffer == 0 || str == 0)
        return;

    //перекодируем символы (для поддержки русского языка)
    static char buf[1024];
    CharToOemA(str,buf);
    str = buf;

    //выход за границы
    int len = (int)strlen(str);
    if (x>=width || y>=height || x+len<=0 || y<0)
        return;

    //обрезка левого края
    if (x<0)
    {
        len += x;
        str -= x;
        x   =  0;
    }

    //обрезка правого края
    if (x+len>width)
        len = width-x;

#ifdef UNICODE
    static wchar_t wstr[1024];
    len = len>1024?1024:len;
    for (int j=0; j<len; ++j)
        mbtowc(&(wstr[j]),&(str[j]),1);
#endif

    //вывод строки
    for (int i=0; i<len; ++i)
    {
#ifdef UNICODE
        buffer[y*width + x+i].Char.UnicodeChar = wstr[i];
#else
        buffer[y*width + x+i].Char.AsciiChar = str[i];
#endif
    }

    //вывод цвета
    PutAttr(x,y,at,len);
}

void PutAttr (int x, int y, WORD at, int len)
{
    if (con == INVALID_HANDLE_VALUE || len <= 0)
        return;
    
    if (x>=width || y>=height || x+len<=0 || y<0)
        return;

    //обрезка левого края
    if (x<0)
    {
        len += x;
        x   =  0;
    }

    //обрезка правого края
    if (x+len>width)
        len = width-x;

    //вывод цвета
    for (int i=0; i<len; ++i)
        buffer[y*width + x+i].Attributes = at;
}

void SetSize (int wd, int hg)
{
    if (con == INVALID_HANDLE_VALUE || wd<=0 || hg<=0)
        return;

    COORD size = {wd,hg};
    SMALL_RECT sm = {0,0,1,1};
    SMALL_RECT rc = {0,0,wd-1,hg-1};

    SetConsoleWindowInfo(con, TRUE, &sm);
    SetConsoleScreenBufferSize(con, size);
    SetConsoleWindowInfo(con, TRUE, &rc);
    SetConsoleScreenBufferSize(con, size);

    SetConsoleActiveScreenBuffer(con);

    width  = wd;
    height = hg;

    if (buffer)
        delete[] buffer;
    buffer = new CHAR_INFO[width*height];
}

void GetSize (int *wd, int *hg)
{
    if (wd) *wd = width;
    if (hg) *hg = height;
}

void SetCurPos (int x, int y)
{
    if (con == INVALID_HANDLE_VALUE)
        return;

    if (x<0) x=0;
    if (x>=width) x=width-1;
    if (y<0) y=0;
    if (y>=height) y=height-1;

    COORD pos = {x,y};
    SetConsoleCursorPosition(con,pos);
}

void GetCurPos (int *x, int *y)
{
    if (x) *x=0;
    if (y) *y=0;

    if (con == INVALID_HANDLE_VALUE)
        return;

    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(con, &info);

    if (x) *x=info.dwCursorPosition.X;
    if (y) *y=info.dwCursorPosition.Y;
}

void ShowCur (bool show)
{
    if (con == INVALID_HANDLE_VALUE)
        return;

    CONSOLE_CURSOR_INFO info;
    GetConsoleCursorInfo(con,&info);
    info.bVisible = show ? TRUE : FALSE;
    SetConsoleCursorInfo(con,&info);
}

void Clear (WORD at)
{
    if (con == INVALID_HANDLE_VALUE)
        return;

    FillRect(0,0,width,height,' ',at);
}

char GetChar (int x, int y)
{
    if (con == INVALID_HANDLE_VALUE)
        return ' ';

    if (x<0 || x>=width)
        return ' ';
    if (y<0 || y>=height)
        return ' ';
    if (!buffer)
        return ' ';

    return buffer[y*width+x].Char.AsciiChar;
}

WORD GetAttr (int x, int y)
{
    if (con == INVALID_HANDLE_VALUE)
        return ' ';

    if (x<0 || x>=width)
        return ' ';
    if (y<0 || y>=height)
        return ' ';
    if (!buffer)
        return ' ';

    return buffer[y*width+x].Attributes;
}

void FillRect (int x, int y, int wd, int hg, char ch, WORD at)
{
    if (con == INVALID_HANDLE_VALUE || buffer==0)
        return;

    //прямоугольник выходит за пределы окна
    if (x>=width || y>=height)
        return;
    if (x+wd<0 || y+hg<0)
        return;
    if (wd<0 || hg<0)
        return;

    //обрезка прямоугольника
    if (x<0)
    {
        wd += x;
        x=0;
    }
    if (y<0)
    {
        hg += y;
        y=0;
    }
    if (x+wd>width)
        wd=width-x;
    if (y+hg>height)
        hg=height-y;

    //поменяем кодировку
    char str[]={ch, 0};
    char oem[]={' ',0};
    CharToOemA(str,oem);
    ch = oem[0];

#ifdef UNICODE
    char    src[] = {ch,0};
    wchar_t dst[] = {0,0};
    mbtowc(dst,src,1);

    wchar_t wchar = dst[0];
#endif

    //заполнение прямоугольника
    for (int i=x; i<x+wd; ++i)
        for (int j=y; j<y+hg; ++j)
        {
#ifdef UNICODE
            buffer[j*width+i].Char.UnicodeChar = wchar;
#else
            buffer[j*width+i].Char.AsciiChar = ch;
#endif
            buffer[j*width+i].Attributes = at;
        }
}

void Swap ()
{
    if (con == INVALID_HANDLE_VALUE || buffer == 0)
        return;

    COORD      bufsize   = {width,height};
    COORD      bufpos    = {0,0};
    SMALL_RECT targetrec = {0,0,width,height};

    WriteConsoleOutput(con, buffer, bufsize, bufpos, &targetrec);
}

bool IsQueueEmpty ()
{
    DWORD events=0;
    GetNumberOfConsoleInputEvents(con, &events);

    return events==0;
}

Event GetNextEvent ()
{
    Event ev;
    ev.type = Event::Nothing;
    ev.ch   = 0;
    ev.code = 0;
    ev.id   = 0;

    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);

    while (1)
    {
        DWORD readed;
        INPUT_RECORD buf;

        ReadConsoleInput(hStdin, &buf, 1, &readed);
        if (readed == 0) return ev;

        KEY_EVENT_RECORD keyrec;
        MOUSE_EVENT_RECORD mouserec;

        switch(buf.EventType)
        {
        //клавиатурное событие
        case KEY_EVENT:
            keyrec = buf.Event.KeyEvent;

            //тип клавиатурного события
            ev.type = Event::KeyDown;
            if (keyrec.bKeyDown == FALSE)
                ev.type = Event::KeyUp;

            //код клавиши и ее символ
            ev.code = keyrec.wVirtualKeyCode;
            ev.ch = keyrec.uChar.AsciiChar;

            return ev;

        //мышиние события
        case MOUSE_EVENT:
            mouserec = buf.Event.MouseEvent;
            //...
            return ev;
        }
    }

    return ev;
}

//освободим память, если еще не освобождена
static struct BufferReleaser
{
   ~BufferReleaser()
    {
        if (buffer)
        {
            delete[] buffer;
            buffer = 0;
        }
    }
} releaser;
#10
8:58, 24 июня 2009

и маленький пример:

//main.cpp
#include "console.h"

bool run = true; //надо присвоить false если хотим выйти из программы
int  x   = 0,    //х координата игрока
     y   = 1,    //у координата игрока
     ex  = 11,   //x координата выхода
     ey  = 19;   //у координата выхода

//лабиринт
int maze[20][20] = 
{
    {1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1},
    {1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1},
    {1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1},
    {1,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1},
    {1,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1},
    {1,0,1,1,1,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,0,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,1},
    {1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,1},
    {1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1},
    {1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,1},
    {1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
    {1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};

void Draw ()
{
    //очистка экрана (стираем старое изображение)
    Clear();

    //рисуем лабиринт
    int i,j;
    for (i=0; i<20; ++i)
    {
        for (j=0; j<20; ++j)
        {
            if (maze[i][j]==1) PutChar(i,j,"#",RGBI(1,1,1,0,0,0,0,0));
            if (maze[i][j]==0) PutChar(i,j,".",RGBI(0,0,1,1,0,0,0,0));
        }
    }

    //рисуем игрока
    PutChar(x,y,"*");

    //выведем то, что нарисовали, в окно
    Swap();
}

void Move (int dx, int dy)
{
    if (x+dx<0 || x+dx>=20 || y+dy<0 || y+dy>=20)
        return;

    if (maze[x+dx][y+dy]==0)
    {
        x = x+dx;
        y = y+dy;
    }

    if (x==ex && y==ey)
        run = false;
}

int main ()
{
    //настроим окно (размеры, заголовок и скроем мигающий курсор)
    Init(20,20,"управление");
    ShowCur(false);

    while (run)
    {
        //нарисуем лабиринт
        Draw();

        //получим событие от клавиатуры
        Event e = GetNextEvent();

        //реакция программы на нажатия клавиш
        if (e.type == Event::KeyDown)
        {
            if (e.code == VK_ESCAPE) run = false;
            if (e.code == VK_LEFT  ) Move(-1, 0);
            if (e.code == VK_RIGHT ) Move( 1, 0);
            if (e.code == VK_UP    ) Move( 0,-1);
            if (e.code == VK_DOWN  ) Move( 0, 1);
        }
    }

    //завершим работу
    Done();
}
#11
9:16, 24 июня 2009

dub
Что такое _snprintf_s? GCC такого не знает.

#12
12:36, 24 июня 2009

X512
>Что такое _snprintf_s? GCC такого не знает

http://msdn.microsoft.com/ru-ru/library/f30dzcf6.aspx

#13
21:52, 6 сен 2009

Что бы код (см. ниже) выводил текст корректно, нужно в свойствах командной строки установить шрифт Lucida Console

#include <stdio.h>
#include <windows.h>

int main()
{
    system("chcp 1251");
    printf("%s\n","Русский текст");
    return 0;
}
#14
1:05, 7 сен 2009

dub
Ты забыл добавить, что это код Джона Ромеро.

Страницы: 1 2 Следующая »
ПрограммированиеFAQОбщее

Тема в архиве.