Подключение русского языка в c windows

Русский язык в консоли, возможно ли Visual C++ Решение и ответ на вопрос 61113

я пишу
setlocale(0,»»);
или
setlocale(LC_ALL, «rus»);
обычно помогает….

НО сейчас проблема в другом.. вывод не хочет корректно выполнять, вместо последней строки, после «Результат» выводит фигню:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// №1.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <iostream>
#include <locale.h>
 
#include "windows.h"
using namespace std;
 
int isint(char *);
void Transf(char *string, char *substring1, char *substring2, int n, int l);
int main(void)
{//setlocale(0,"");
 setlocale(LC_ALL, "rus");
 SetConsoleTitle(_T("Программа демонстрирует работу функции Тransf."));
 char string[256];
 char substring1[256];
 char substring2[256];
 char tmp[256];
 int n,l,strLength;
 printf("Введите 1ю строку: n");
 gets(string);
 strLength = strlen(string);
 do{ printf("Введите 2ю строку: n");
  gets(substring1);
  printf("Введите 3ю строку: n");
  gets(substring2); 
  if(strlen(substring1)==strlen(substring2))
   break;
  else  {printf("Длина 2й строки должна быть эквивалентна длине строки 3!n");
   continue;  } }while(1);
 do{  printf("Введите начальную позицию для сравнения, которая должна быть меньше %i n", strLength);
  scanf("%s",tmp);
    if((n=isint(tmp))==0)continue;  
  if(n>strLength-1||n<1){
   printf("Некореектный ввод, посторите снова!!! n");
   continue;  }
  printf("Введите количество символов для сравнения, которое дожно быть больше 0 и меньше %i n",strLength-n+1);
  scanf("%s", &tmp);
    if((l=isint(tmp))==0)continue;
  if(l<1||l>strLength||isdigit(l)!=0)
  {   printf("Некореектный ввод, посторите снова!!!n");
   continue;  }
  break; }while(1);
  Transf(string,substring1,substring2,n,l);
  printf("Результат выполнения: %cn", &string);
  system("pause");
 return 0;}
 
void Transf(char *string, char *substring1, char *substring2, int n, int l)
{   int i,m,j;
 i=strlen(string)-1; 
 m=strlen(substring1)-1; 
 for(i=n-1;i<l;i++)
 {  for(j=0;j<m;j++)
  {   if(string[i] == substring1[j]) string[i] = substring2[j];  } } }
 
int isint(char *ch)
{int i;
 char tmp[256];
 for(i=0;i<strlen(ch);i++)
 {  if(isdigit(ch[i]))      strcpy(tmp,ch);
  else{
   return 0;
   break;  } }
i=atoi(tmp); 
    return i;}

Добавлено через 3 часа 39 минут
Получилось!
корявенько правда, но я собой довольна

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// №1.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <iostream>
#include <locale.h> 
#include "windows.h"
using namespace std;
 
int isint(char *);
void Transf(char *string, char *substring1, char *substring2, int n, int l);
int main(void)
{   setlocale(LC_ALL,"russian_russia.866");
    SetConsoleTitle(_T("Программа демонстрирует работу функции Тransf."));
 
int n,l,strLength;
char string[256];
 char substring1[256];
 char substring2[256];
 char tmp[256];
 wprintf(L"%s", L"Вввод строки 1:n");
 gets(string);
 strLength = strlen(string);
 do{ wprintf(L"%s", L"Вввод строки 2:n");
  gets(substring1);
  wprintf(L"%s", L"Вввод строки 3:n");
  gets(substring2); 
  if(strlen(substring1)==strlen(substring2))
   break;
  else
  { wprintf(L"%s", L"Длина 2й строки должна быть эквивалентна длине строки 3:n");
   continue;  } }while(1);
 do{
   wprintf(L"%s", L"Введите начальную позицию для сравнения, которая должна быть больше 0 и меньше");
   printf(" %i: n", strLength);
  scanf("%s",tmp);
    if((n=isint(tmp))==0)continue;  
  if(n>strLength-1||n<1){
  wprintf(L"%s", L"Неккоректный ввод, повторите снова!");
   continue;  }
  wprintf(L"%s", L"Введите количество символов для сравнения, которое дожно быть больше 0 и меньше");
   printf(" %i: n", strLength-n+1);
  scanf("%s", &tmp);
    if((l=isint(tmp))==0)continue;
  if(l<1||l>strLength||isdigit(l)!=0)
  {     wprintf(L"%s", L"Неккоректный ввод, повторите снова!");
   continue;  }
  break; }while(1);
  Transf(string,substring1,substring2,n,l);
  wprintf(L"%s", L"Результат выполнения:n");
 //printf("Результат выполнения: %sn", &string);
  printf(string);
  wprintf(L"%s", L"n");
   system(" pause");
 return 0;}
void Transf(char *string, char *substring1, char *substring2, int n, int l)
{ int i,m,j;
 i=strlen(string)-1; 
 m=strlen(substring1)-1; 
 for(i=n-1;i<l;i++)
 {  for(j=0;j<m;j++)
  {   if(string[i] == substring1[j]) string[i] = substring2[j];  } } }
int isint(char *ch)
{ int i;
 char tmp[256];
 for(i=0;i<strlen(ch);i++)
 {  if(isdigit(ch[i]))      strcpy(tmp,ch);
  else{
   return 0;
   break;  } }
i=atoi(tmp); 
    return i;}



0



На начальных этапах программирования многие новички сталкиваются с такой проблемой: они в коде пишут какое-либо сообщение на русском языке для консоли (например, используя printf), но при запуске программы вместо русских слов появляются какие-то непонятные знаки. Покажем, как избавиться от этой проблемы.

Например, при запуске вот этой программы:

#include «stdafx.h»

#include <conio.h>

int _tmain(int argc, _TCHAR* argv[])

{

    printf(«Всем привет! Как дела?»);

    _getch();

    return 0;

}

В консоли будет отображено следующее:

Как включить русский язык в Си - vscode.ru

Всё дело в том, что мы не подключили русскую локализацию.

Исправить эту ошибку  очень легко!

Для начала надо добавить следующую библиотеку:

Она отвечает за локализацию.

А затем нам надо просто написать в начале тела кода вот эту строку:

setlocale(LC_ALL, «Rus»);

Функция setlocale задаёт локализацию программы. По умолчанию это только английский язык.
LC_ALL указывает программе, что локализированы будут все функции.

«Rus», как легко догадаться говорит о том, что локализация произойдёт на русский язык.

Вот и всё! Мы включили русский язык в Си. Наша программа модернизирована и обогащена на две строки. Теперь она будет выглядеть вот так:

#include «stdafx.h»

#include <conio.h>

#include <locale.h>

int _tmain(int argc, _TCHAR* argv[])

{

    setlocale(LC_ALL, «Rus»);

    printf(«Всем привет! Как дела?»);

    _getch();

    return 0;

}

А консоль вот так:

Как включить русский язык в Си - vscode.ru

Для данной задачи существует множество решений. Если вам нужно быстрое и не обязательно универсальное решение, чтобы сильно не разбираться, прокручивайте к разделу «Менее правильные, но пригодные решения».

Правильное, но сложное решение

Для начала, проблема у консоли Windows состоит в том, что её шрифты, которые стоят «по умолчанию», показывают не все символы. Вам следует сменить шрифт консоли на юникодный, это позволит работать даже на английской Windows. Если вы хотите поменять шрифт только для вашей программы, в её консоли нажмите на иконку в левом верхнем углу → Свойства → Шрифт. Если хотите поменять для всех будущих программ, то же самое, только заходите в Умолчания, а не Свойства.

Lucida Console и Consolas справляются со всем, кроме иероглифов. Если ваши консольные шрифты позволят, вы сможете вывести и , если нет, то лишь те символы, которые поддерживаются.

Дальнейшее рассмотрение касается лишь Microsoft Visual Studio. Если у вас другой компилятор, пользуйтесь предложенными на свой страх и риск, никакой гарантии нету.

Теперь, кодировка входных файлов компилятора. Компилятор Microsoft Visual Studio (по крайней мере, версии 2012 и 2013) компилирует исходники в однобайтных кодировках так, как будто бы они на самом деле в ANSI-кодировке, то есть для случая русской системы — CP1251. Это означает, что кодировка исходников в CP866 — неправильна. (Это важно, если вы используете L"..."-строки.) С другой стороны, если вы храните исходники в CP1251, то эти же исходники не будут нормально собираться на нерусской Windows. Поэтому стоит хранить исходники в Unicode (например, UTF-8).

Настроив среду, перейдём к решению собственно задачи.

Правильным решением является уйти от однобайтных кодировок, и использовать Unicode в программе. При этом вы получите правильный вывод не только кириллицы, но и поддержку всех языков (изображение отсутствующих в шрифтах символов будет отсутствовать, но вы сможете с ними работать). Для Windows это означает переход с узких строк (char*, std::string) на широкие (wchar_t*, std::wstring), и использование кодировки UTF-16 для строк.

(Ещё одна проблема, которую решает использование широких строк: узкие строки при компиляции кодируются в однобайтную кодировку используя текущую системную кодовую страницу, то есть, ANSI-кодировку. Если вы компилируете вашу программу на английской Windows, это приведёт к очевидным проблемам.)

Вам нужно _setmode(_fileno(...), _O_U16TEXT); для переключения режима консоли:

#include <iostream>
#include <io.h>
#include <fcntl.h>

int wmain(int argc, wchar_t* argv[])
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin),  _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);

    std::wcout << L"Unicode -- English -- Русский -- Ελληνικά -- Español." << std::endl;
    // или
    wprintf(L"%s", L"Unicode -- English -- Русский -- Ελληνικά -- Español.n");

    return 0;
}

Такой способ должен работать правильно с вводом и выводом, с именами файлов и перенаправлением потоков.

Важное замечание: потоки ввода-вывода находятся либо в «широком», либо в «узком» состоянии — то есть, в них выводится либо только char*, либо только wchar_t*. После первого вывода переключение не всегда возможно. Поэтому такой код:

cout << 5;            // или printf("%d", 5);
wcout << L"привет";   // или wprintf(L"%s", L"привет");

вполне может не сработать. Используйте только wprintf/wcout.


Если очень не хочется переходить на Unicode, и использовать однобайтную кодировку, будут возникать проблемы. Для начала, символы, не входящие в выбранную кодировку (например, для случая CP1251 — базовый английский и кириллица), работать не будут, вместо них будет вводиться и выводиться абракадабра. Кроме того, узкие строковые константы имеют ANSI-кодировку, а это значит, что кириллические строковые литералы на нерусской системе не сработают (в них будет зависимая от системной локали абракадабра). Держа в голове эти проблемы, переходим к изложению следующей серии решений.

Менее правильные, но пригодные решения

В любом случае, поставьте юникодный шрифт в консоли. (Это первый абзац «сложного» решения.)

Убедитесь, что ваши исходники в кодировке CP 1251 (это не само собой разумеется, особенно если у вас не русская локаль Windows). Если при добавлении русских букв и сохранении Visual Studio ругается на то, что не может сохранить символы в нужной кодировке, выбирайте CP 1251.

(1) Если компьютер ваш, вы можете поменять кодовую страницу консольных программ на вашей системе. Для этого сделайте вот что:

  1. Запустите Regedit.
  2. На всякий пожарный экспортируйте куда-нибудь реестр (этот шаг все почему-то пропускают, так что когда всё сломается, мы вас предупреждали).
  3. В разделе HKEY_CURRENT_USERConsole найдите ключ CodePage (если нету, создайте ключ с таким названием и типом DWORD).
  4. Установите значение по ключу (левая клавиша/изменить/Система счисления = десятичная) на 1251.
  5. Не забудьте перегрузиться после изменений в реестре.

Преимущества способа: примеры из книг начнут работать «из коробки». Недостатки: смена реестра может повлечь за собой проблемы, кодировка консоли меняется глобально и перманентно — это может повлиять сломать другие программы. Плюс эффект будет только на вашем компьютере (и на других, у которых та же кодировка консоли). Плюс общие проблемы неюникодных способов.

Примечание. Установка глобальной кодовой страницы консоли через параметр реестра HKEY_CURRENT_USERConsoleCodePage не работает в Windows 10, вместо него будет использована кодовая страница OEM — предположительно баг в conhost. При этом установка кодовой страницы консоли на уровне конкретного приложения (HKEY_CURRENT_USERConsole(путь к приложению)CodePage) работает.

(2) Вы можете поменять кодировку только вашей программы. Для этого нужно сменить кодировку консоли программным путём. Из вежливости к другим программам не забудьте потом вернуть кодировку на место!

Это делается либо при помощи вызова функций

SetConsoleCP(1251);
SetConsoleOutputCP(1251);

в начале программы, либо про помощи вызова внешней утилиты

system("chcp 1251");

(То есть, у вас должно получиться что-то вроде

#include <cstdlib>  

int main(int argc, char* argv[])
{
    std::system("chcp 1251");
    ...

или

#include <Windows.h>

int main(int argc, char* argv[])
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    ...

и дальше обыкновенный код программы.)

Можно обернуть эти вызовы в класс, чтобы воспользоваться плюшками автоматического управления временем жизни объектов C++.

Пример:

#include <iostream>
#include <string>

int chcp(unsigned codepage)
{
    // составить команду из кусочков
    std::string command("chcp ");
    command += codepage;
    // выполняем команду и возвращаем результат
    return !std::system(command.c_str());
}

// этот код будет запущен перед main
static int codepage_is_set = chcp(1251);

(если выполняете задание из Страуструпа можно вставить в конец заголовочного файла std_lib_facilities.h)

Или так:

#include <windows.h>

class ConsoleCP
{
    int oldin;
    int oldout;

public:
    ConsoleCP(int cp)
    {
        oldin = GetConsoleCP();
        oldout = GetConsoleOutputCP();
        SetConsoleCP(cp);
        SetConsoleOutputCP(cp);
    }

    // поскольку мы изменили свойства внешнего объекта — консоли, нам нужно
    // вернуть всё как было (если программа вылетит, пользователю не повезло)
    ~ConsoleCP()
    {
        SetConsoleCP(oldin); 
        SetConsoleOutputCP(oldout);
    }
};

// и в программе:    
int main(int argc, char* argv[])
{
    ConsoleCP cp(1251);
    std::cout << "русский текст" << std::endl;
    return 0;
}

Если вам нужен не русский, а какой нибудь другой язык, просто замените 1251 на идентификатор нужной кодировки (список указан ниже в файле), но, разумеется, работоспособность не гарантируется.

Остались методы, которые тоже часто встречаются, приведём их для полноты.

Методы, которые работают плохо (но могут помочь вам)

Метод, который часто рекомендуют — использование конструкции setlocale(LC_ALL, "Russian"); У этого варианта (по крайней мере в Visual Studio 2012) гора проблем. Во-первых, проблема с вводом русского текста: введённый текст передаётся в программу неправильно! Нерусский текст (например, греческий) при этом вовсе не вводится с консоли. Ну и общие для всех неюникодных решений проблемы.

Ещё один метод, не использующий Unicode — использование функций CharToOem и OemToChar. Этот метод требует перекодировки каждой из строк при выводе, и (кажется) слабо поддаётся автоматизации. Он также страдает от общих для неюникодных решений недостатков. Кроме того, этот метод не будет работать (не только с константами, но и с runtime-строками!) на нерусской Windows, т. к. там OEM-кодировка не будет совпадать с CP866. В дополнение можно так же сказать что эти функции поставляются не со всеми версиями Visual Studio — например в некоторых версиях VS Express их просто нет.


Источники:

  1. Как выводить на экран и вводить данные типа wchar_t[]?
    • к сожалению, автор того вопроса пользовался компилятором MinGW под Cygwin и WinXP, что делает большинство современных решений неприменимыми.
  2. Output unicode strings in Windows console app
  3. Conventional wisdom is retarded, aka What the @#%&* is _O_U16TEXT?
  4. What’s the difference between printf(“%s”), printf(“%ls”), wprintf(“%s”), and wprintf(“%ls”)?
  5. Русский язык в исходном коде в Dev C++
  6. Code Page Identifiers

Как подключить поддержку русского языка на языке программирования Си?

Чтобы вывести обычный русский текст в консоли C++, нужно прописать функцию setlocale:

И тогда будет писаться стандартный русский язык, как показано на скриншоте:

При желании можно упростить последний аргумент в скобках setlocale(LC_ALL, «Russian»); и прописать его следующим образом setlocale(0, «»); — все полностью идентично и ничего не поменяется.

При изучении языка C++ и программировании под Windows довольно часто возникают вопросы по поводу отображения русских букв в консоли. Вывод и ввод русских букв сопровождается выводом и вводом каких-то кракозябр или иероглифов. В интернете можно найти довольно много советов, но большая часть советов, которые мне попались, не помогали в решении проблемы.

Возникла проблема с отображением русских букв

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

На языке C++ программирую под ОС Linux, использую компилятор GCC. С проблемой неправильного отображения русских букв я не сталкивался. В момент написания статьи я нахожусь далеко от своего компьютера, могу довольствоваться лишь скромненьким ноутбуком с установленной ОС Windows Seven. Захотелось покодить и я установил на него интегрированную среду разработки Dev-C++ 5.10(использует компилятор TDM-GCC 4.8.1 на базе GCC 4.8.1). Кстати, она уже официально не поддерживается, но существует форк Orwell Dev-C++, который обновляется по сей день. Установив, я запустил и для пробы написал простую программку, которая отображает текст «Привет, мир!». Но поздороваться она с миром так и не смогла, а лишь сказала что-то непонятное на древнеегипетском. После перелопачивания некоторых форумов и сайтов я нашел множество советов, но основная масса не способна была решить её полностью, образовывались подводные камни о которых расскажу далее.

После написания, компиляции и запуска такой программы:

Можно получить примерно такой результат

Вывод кракозябр в консоль

Сразу понятно, что на приветствие это совсем не похоже.

После прочтения кучи советов стало понятно, что большая часть советов предлагала решить проблему функцией setlocale(), которая находится в заголовочном файле <clocale>.

Последовав совету и усовершенствовав программу таким образом:

Дополнительно: можно было написать setlocale(0, «») и результат был бы аналогичным, при условии, что в настройках ОС язык системы русский.

На вывод я получил следующий результат

Отлично, подумал я. Казалось бы, что проблема решена и программа здоровается на родном языке, но вот именно здесь оказались подводные камни.

О них я узнал из обсуждения. У человека была аналогичная проблема, решенная таким образом. Но решение удовлетворяло его недолго, он сообщил, что программа при вводе данных и последующем их выводе не выводит на руском, она говорит на непонятном языке.

Коль уж так, я решил вновь внести изменения в программу, пусть она поздоровается со мной по имени.

Но в результате я получил не приветствие

Оскорбление на древнеегипетском?

Как видно, она не смогла назвать моего имени.

Поискав информацию в сети, я узнал о том, что setlocale() не работает с потокоми ввода/вывода, а то есть с cin,cout,etc. Выходит, что нужно искать альтернативные способы решения данной проблемы, которые предлагались на других сайтах.

Решение проблемы с отображением русских букв в консоли

По-другому решить проблему можно было воспользовавшись функциями SetConsoleCP() и SetConsoleOutputCP() с аргуменом 1251 в обеих. Эти функции требуют подключения заголовка <Windows.h>, практически в каждом компиляторе под Windows он имеется, проблем не будет.

Усовершенствовал программу таким образом

На вывод получил

Вновь кракозябры в консоли

Вновь кракозябры в консоли

Снова что-то непонятное. Но решение, как оказалось, находилось очень близко. У функций SetConsoleCP() и SetConsoleOutputCP() есть небольшой недостаток — они работают только со шрифтом Lucida Console. В консоли же по умолчанию стоит шрифт Consolas, либо точечные шрифты. Следующим этапом сделать нужно вот что. Находясь в консоли нажать кнопку Cmd или нажать на значек программы в левом верхнем углу(Перед D:… в названии), то есть вызвать контекстное меню окна. Далее нажать «Свойства».

Контекстное меню консоли

Контекстное меню консоли

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

Свойства консоли Windows

Свойства консоли Windows

И нажать на кнопку ОК.

После такой процедуры я вновь запустил программу и…

Работа программы

Да! Она поздоровалась со мной по имени на русском языке.

Данный способ помог решить мне проблему с отображением русских символов в консоли Windows, надеюсь, что кому-нибудь еще он тоже поможет. Спасибо за внимание.

Для вас это может быть интересно:

Русские символы(буквы) при вводе/выводе в консоль на C++ : 29 комментариев

Блин все делаю как показано но все равно не получается в свойствах консоли установлен шрифт Lucida Console может поможете)
Пишу:
#include
#include
#include

using namespace std;

int main()
setlocale(LC_ALL,»Russian»);
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cout << «Привет, Мир!»;
return 0;
>

  1. Nicknixer Автор записи 07.12.2015

Проверил у себя — всё работает и отображает верно. Попробуйте набрать такую же программу, как на рисунке здесь http://nicknixer.ru/?p=349

Строчка setlocale(LC_ALL,»Russian») не нужна, без нее все работает.

тебе нужно понять что тебе нужно, если только вывести текст то оставь setlocal(LC_ALL, «Russian»)
ну а если у тебя будет переменная напримере кода
int main()
char name [12];
cout << «как тебя зовут?»;
cin << name;
cout << «привет, » << name;
return 0;
>
то получится что ничего не получится, в этом случае используй setconsolecp(1251); setconsoleoutputcp(1251); и тогда всё будет корректно отображаться. по поводу программы ide я использую visual studios 2019 и всё нормально работает

В консоли 866 кодовая страница. Можно проще — Creator — Настройки — редактор — кодовая страница 866. Заработает самая первая программа.

Спасибо за 866 кодовую таблицу, все заработало.

Мучался 2 часа с выводом русских букв!
Перечитал кучу пустых советов.
Наконец-то.
Этот— самый толковый способ сделать так, чтобы все работало, и писало по русски!!
Благодарю Вас.

  1. Nicknixer Автор записи 14.10.2016

Я рад тому, что это помогло мне, Вам и другим людям.

Вижу, что не только в вебе проблема с отображением русских букв. PHP- программисты с вами!

Большое человеческое спасибо!
Очень помогли дельным советом. Всё работает как надо!

Спасибо!по полочкам и правильно всё разложено)

На мой взгляд, самый простой и действенный способ вывода русских букв в консоли Windows: писать исходники в ее родной кодировке, т. е. в OEM866 и проблем никаких не возникнет. Тем более, что почти все текстовые редакторы ее поддерживают. Для удобства можно установить эту кодировку по умолчанию в тот же Notepad++.
И не надо танцевать с бубном, подключать заголовки, использовать дополнительные функции, менять шрифты и т.д.

Спасибо, дай те бог здоровья!!

Благодарю за эти советы, они действующие, доходчивые. Ушла минута на то, что долго не мог сделать

6 часов искал ответ!Спасибо !

Лайфхак от «Специалист»
После main
system(«chcp 1251 > nul»);

Имеется ввиду после фигурных скобок, т.е. в тело программы

Вообще-то setlocale() и всё вокруг неё касается преобразований WCHAR -> BYTE -> WCHAR у CRT функций (ну например если выводить тот-же самый «Привет мир» вот так:

setlocale( LC_ALL, «.OCP» );
wprintf(L»Привет мир!»);

То будет уже профит.
В свою очередь SetConsoleOutputCP() нужна примерно для того-же — на Винде с чужой кодировкой выводить юникодные строки кирилицей.
ну а так Taras Lavrov верно указал как это для неюникодных программ делается.

Спасибо большое!Очень помогло.С начала про поток вывода узнал где то недели 2 назад, вчера заинтересовало почему поток ввода не работает. Менее минуты и вуаля. Надеюсь ругаться там не будет никто на счёт заголовочных файлов, но…ОС у всех разные, преобразователи (компиляторы) разные. Вот поэтому и советы для всех разные. Кому то кодировку сменить, а многим многим остальным дополнительные код надо писать. Может когда напишем собственную ОС(хотя кое что такое у нас было когда то давно) тогда ничего этого не надо будет. Автору статьи большое спасибо ещё раз. Русский язык стараюсь вписать куда угодно лишь бы было по русски. Надеюсь, это никого не задевает

Почему не выводится кириллица из Си в консоль windows?

Погуглив нашел 2 способа локализации, но ни один не сработал. (еще один способ с подключением Windows.h) Как все таки выводить кириллицу в консоль?

  • Вопрос задан более трёх лет назад
  • 1273 просмотра
  • Facebook
  • Вконтакте
  • Twitter
  • Facebook
  • Вконтакте
  • Twitter

evg_96, Если у вас английская винда, то совет с СР866 отменяется. Ну и как бэ в консоль с CP437 вывести русские буквы не возможно — там их просто нет (не верите? посмотрите ASCII table для этой кодировки). И мой комментарий к статье вы не прочитали.
Русский язык в винде установлен? Переводите консоль в одну из русских кодировок: cp866 или cp1251 конвертируйте исходники в соответствующую кодировку и все будет выводится.
Команда консоли для перевода кодировки:
chcp 866 или chcp1251, но можно перевести кодировку и программно с помощью функций WinAPI — SetConsoleCP/GetConsoleCP.

PS: вопрос с кодировкой достаточно не простой, поэтому на нем многие спотыкаются в начале. Я думаю, что если вы не собираетесь в дальнейшем разрабатывать утилиты командной строки, то можно и не заморачиваться с этим. Хотя, если разберетесь в теме, то вам будет первый «+ в карму».

Время прочтения
9 мин

Просмотры 22K

Введение

Консольные приложения до сих пор остаются наиболее востребованным видом приложений, большинство разработчиков оттачивают архитектуру и бизнес-логику именно в консоли. При этом они нередко сталкиваются с проблемой локализации — русский текст, который вполне адекватно отражается в исходном файле, при выводе на консоль приобретает вид т.н. «кракозябр».

В целом, локализация консоли Windows при наличии соответствующего языкового пакета не представляется сложной. Тем не менее, полное и однозначное решение этой проблемы, в сущности, до сих пор не найдено. Причина этого, главным образом, кроется в самой природе консоли, которая, являясь компонентом системы, реализованным статическим классом System.Console, предоставляет свои методы приложению через системные программы-оболочки, такие как командная строка или командный процессор (cmd.exe), PowerShell, Terminal и другие.
По сути, консоль находится под двойным управлением — приложения и оболочки, что является потенциально конфликтной ситуацией, в первую очередь в части использования кодировок.

Данный материал не предлагает строгий алгоритм действий, а направлен на описание узловых проблем, с которыми неизбежно сталкивается разработчик локализованного консольного приложения, а также некоторые возможные пути их разрешения. Предполагается, что это позволит разработчику сформировать стратегию работы с локализованной консолью и эффективно реализовать существующие технические возможности, большая часть которых хорошо описана и здесь опущена.

Виды консолей

В общем случае функции консоли таковы:

  • управление операционной системой и системным окружением приложений на основе применения стандартных системных устройств ввода-вывода (экран и клавиатура), использования команд операционной системы и/или собственно консоли;

  • запуск приложений и обеспечение их доступа к стандартным потокам ввода-вывода системы, также с помощью стандартных системных устройств ввода-вывода.

Основная консоль Windows — командная строка или иначе командный процессор (CMD). Большие возможности предоставляют оболочки PowerShell (PS), Windows PowerShell (WPS) и Terminal. По умолчанию Windows устанавливает Windows Power Shell мажорной версией до 5, однако предлагает перейти на новую версию — 7-ку, имеющую принципиальное отличие (вероятно, начинающееся с 6-ки) — кроссплатформенность. Terminal — также отдельно уставливаемое приложение, по сути интегратор всех ранее установленных оболочек PowerShell и командной строки.

Отдельным видом консоли можно считать консоль отладки Visual Studio (CMD-D).

Конфликт кодировок

Полностью локализованная консоль в идеале должна поддерживать все мыслимые и немыслимые кодировки приложений, включая свои собственные команды и команды Windows, меняя «на лету» кодовые страницы потоков ввода и вывода. Задача нетривиальная, а иногда и невозможная — кодовые страницы DOS (CP437, CP866) плохо совмещаются с кодовыми страницами Windows и Unicode.

История кодировок здесь: О кодировках и кодовых страницах / Хабр (habr.com)

Исторически кодовой страницей Windows является CP1251 (Windows-1251, ANSI, Windows-Cyr), уверенно вытесняемая 8-битной кодировкой Юникода CP65001 (UTF-8, Unicode Transformation Format), в которой выполняется большинство современных приложений, особенно кроссплатформенных. Между тем, в целях совместимости с устаревшими файловыми системами, именно в консоли Windows сохраняет базовые кодировки DOS — CP437 (DOSLatinUS, OEM) и русифицированную CP866 (AltDOS, OEM).

Совет 1. Выполнять разработку текстовых файлов (программных кодов, текстовых данных и др.) исключительно в кодировке UTF-8. Мир любит Юникод, а кроссплатформенность без него вообще невозможна.

Совет 2. Периодически проверять кодировку, например в текстовом редакторе Notepad++. Visual Studio может сбивать кодировку, особенно при редактировании за пределами VS.

Поскольку в консоли постоянно происходит передача управления от приложений к собственно командному процессору и обратно, регулярно возникает «конфликт кодировок», наглядно иллюстрируемый таблица 1 и 2, сформированных следующим образом:

Были запущены три консоли — CMD, PS и WPS. В каждой консоли менялась кодовая страница с помощью команды CHCP, выполнялась команда Echo c двуязычной строкой в качестве параметра (табл. 1), а затем в консоли запускалось тестовое приложение, исходные файлы которого были созданы в кодировке UTF-8 (CP65001): первая строка формируется и направляется в поток главным модулем, вторая вызывается им же, формируется в подключаемой библиотеке классов и направляется в поток опять главным модулем, третья строка полностью формируется и направляется в поток подключаемой библиотекой.

Команды и код приложения под катом

команды консоли:

  • > Echo ffffff фффффф // в командной строке

  • PS> Echo ffffff фффффф // в PowerShell

  • PS> Echo ffffff ?????? // так выглядит та же команда в Windows PowerShell

код тестового приложения:

using System;
using ova.common.logging.LogConsole;
using Microsoft.Extensions.Logging;
using ova.common.logging.LogConsole.Colors;

namespace LoggingConsole.Test
{
    partial class Program
    {
        static void Main2(string[] args)
        {
            ColorLevels.ColorsDictionaryCreate();
            Console.WriteLine("Hello World! Привет, мир!");     //вывод строки приветствия на двух языках
            LogConsole.Write("Лог из стартового проекта", LogLevel.Information);
            Console.WriteLine($"8. Active codepage: input {Console.InputEncoding.CodePage}, output {Console.OutputEncoding.CodePage}");
            Console.ReadKey();
        } 
    }
}

Командную часть задания все консоли локализовали практически без сбоев во всех кодировках, за исключением: в WPS неверно отображена русскоязычная часть команды во всех кодировках.

Табл. 1. Результат выполнения команды консоли Echo ffffff фффффф

Табл. 1. Результат выполнения команды консоли Echo ffffff фффффф

Вывод тестового приложения локализован лишь в 50% испытаний, как показано в табл.2.

Табл. 2. Результат запуска приложения LoggingConsole.Test

Табл. 2. Результат запуска приложения LoggingConsole.Test

Сoвет 3. Про PowerShell забываем раз и навсегда. Ну может не навсегда, а до следующей мажорной версии…

По умолчанию Windows устанавливает для консоли кодовые страницы DOS. Чаще всего CP437, иногда CP866. Актуальные версии командной строки cmd.exe способны локализовать приложения на основе русифицированной кодовой страницы 866, но не 437, отсюда и изначальный конфликт кодировок консоли и приложения. Поэтому

Совет 4. Перед запуском приложения необходимо проверить кодовую страницу консоли командой CHCP и ей же изменить кодировку на совместимую — 866, 1251, 65001.

Совет 5. Можно установить кодовую страницу консоли по умолчанию. Кратко: в разделе реестра HKEY_LOCAL_MACHINESOFTWAREMicrosoftCommand Processor добавить или изменить значение параметра Autorun на: chcp <номер кодовой страницы>. Очень подробно здесь: Изменить кодовую страницу консоли Windows по умолчанию на UTF-8 (qastack.ru), оригинал на английском здесь: Change default code page of Windows console to UTF-8.

Проблемы консолей Visual Studio

В Visual Studio имеется возможность подключения консолей, по умолчанию подключены командная строка для разработчика и Windows PowerShell для разработчика. К достоинствам можно отнести возможности определения собственных параметров консоли, отдельных от общесистемных, а также запуск консоли непосредственно в директории разработки. В остальном — это обычные стандартные консоли Windows, включая, как показано ранее, установленную кодовую страницу по умолчанию.

Отдельной опцией Visual Studio является встроенная односеансная консоль отладки, которая перехватывает команду Visual Studio на запуск приложения, запускается сама, ожидает компиляцию приложения, запускает его и отдает ему управление. Таким образом, отладочная консоль в течение всего рабочего сеанса находится под управлением приложения и возможность использования команд Windows или самой консоли, включая команду CHCP, не предусмотрена. Более того, отладочная консоль не воспринимает кодовую страницу по умолчанию, определенную в реестре, и всегда запускается в кодировке 437 или 866.

Совет 6. Тестирование приложения целесообразно выполнять во внешних консолях, более дружелюбных к локализации.

Анализ проблем консолей был бы не полон без ответа на вопрос — можно ли запустить консольное приложение без консоли? Можно — любой файл «.exe» запустится двойным кликом, и даже откроется окно приложения. Однако консольное приложение, по крайней мере однопоточное, по двойному клику запустится, но консольный режим не поддержит — все консольные вводы-выводы будут проигнорированы, и приложение завершится

Локализация отладочной консоли Visual Studio

Отладочная консоль — наиболее востребованная консоль разработчика, гораздо более удобная, чем внешняя консоль, поэтому резонно приложить максимум усилий для ее локализации.

На самом деле, правильнее говорить о локализации приложения в консоли — это важное уточнение. Microsoft по этому поводу высказывается недвусмысленно: «Programs that you start after you assign a new code page use the new code page. However, programs (except Cmd.exe) that you started before assigning the new code page will continue to use the original code page». Иными словами, консоль можно локализовать когда угодно и как угодно, но приложение будет локализовано в момент стабилизации взаимодействия с консолью в соответствии с текущей локализацией консоли, и эта локализация сохранится до завершения работы приложения. В связи с этим возникает вопрос — в какой момент окончательно устанавливается связь консоли и приложения?

Важно! Приложение окончательно стабилизирует взаимодействие с консолью в момент начала ввода-вывода в консоль, благодаря чему и появляется возможность программного управления локализацией приложения в консоли — до первого оператора ввода-вывода.

Ниже приведен пример вывода тестового приложения в консоль, иллюстрирующий изложенное. Метод Write получает номера текущих страниц, устанавливает новые кодовые страницы вводного и выводного потоков, выполняет чтение с консоли и записывает выводную строку, содержащий русский текст, в том числе считанный с консоли, обратно в консоль. Операция повторяется несколько раз для всех основных кодовых страниц, упомянутых ранее.

F:LoggingConsole.TestbinReleasenet5.0>chcp
Active code page: 1251

F:LoggingConsole.TestbinReleasenet5.0>loggingconsole.test
Codepages: current 1251:1251, setted 437:437, ΓΓεΣΦ∞ 5 ±Φ∞ΓεδεΓ ∩ε-≡≤±±ΩΦ: Θ÷≤Ωσ=Θ÷≤Ωσ
Codepages: current 437:437, setted 65001:65001,  5  -: =
Codepages: current 65001:65001, setted 1252:1252, ââîäèì 5 ñèìâîëîâ ïî-ðóññêè: éöóêå=éöóêå
Codepages: current 1252:1252, setted 1251:1251, вводим 5 символов по-русски: йцуке=йцуке
Codepages: current 1251:1251, setted 866:866, ттюфшь 5 ёшьтюыют яю-Ёєёёъш: щЎєъх=щЎєъх
Codepages: current 866:866, setted 1251:1251, вводим 5 символов по-русски: йцуке=йцуке
Codepages: current 1251:1251, setted 1252:1252, ââîäèì 5 ñèìâîëîâ ïî-ðóññêè: éöóêå=éöóêå

F:LoggingConsole.TestbinReleasenet5.0>chcp
Active code page: 1252
  • приложение запущено в консоли с кодовыми страницами 1251 (строка 2);

  • приложение меняет кодовые страницы консоли (current, setted);

  • приложение остановлено в консоли с кодовыми страницами 1252 (строка 11, setted);

  • по окончании работы приложения изменения консоли сохраняются (строка 14 — Active codepage 1252);

  • Приложение адекватно локализовано только в случае совпадения текущих кодовых страниц консоли (setted 1251:1251) с начальными кодовыми страницами (строки 8 и 10).

Код тестового приложения под катом

using System;
using System.Runtime.InteropServices;

namespace LoggingConsole.Test
{
    partial class Program
    {
        [DllImport("kernel32.dll")] static extern uint GetConsoleCP();
        [DllImport("kernel32.dll")] static extern bool SetConsoleCP(uint pagenum);
        [DllImport("kernel32.dll")] static extern uint GetConsoleOutputCP();
        [DllImport("kernel32.dll")] static extern bool SetConsoleOutputCP(uint pagenum);
        
        static void Main(string[] args)
        {
            Write(437);
            Write(65001);
            Write(1252);
            Write(1251);
            Write(866);
            Write(1251);
            Write(1252);
         }

        static internal void Write(uint WantedIn, uint WantedOut)
        {
            uint CurrentIn = GetConsoleCP();
            uint CurrentOut = GetConsoleOutputCP();
            Console.Write($"current {CurrentIn}:{CurrentOut} - текущая кодировка, "); /*wanted {WantedIn}:{WantedOut},*/
            SetConsoleCP(WantedIn);
            SetConsoleOutputCP(WantedOut);
            Console.Write($"setted {GetConsoleCP()}:{GetConsoleOutputCP()} - новая кодировка, ");
            Console.Write($"вводим 3 символа по-русски: ");
            string str = "" + Console.ReadKey().KeyChar.ToString();
            str += Console.ReadKey().KeyChar.ToString();
            str += Console.ReadKey().KeyChar.ToString();
            Console.WriteLine($"={str}");
        }
      
        static internal void Write(uint ChangeTo)
        {
            Write(ChangeTo, ChangeTo);
        }
    }
}

Программное управление кодировками консоли — это единственный способ гарантированной адекватной локализацией приложения в консоли. Языки .Net такой возможности не предоставляют, однако предоставляют функции WinAPI: SetConsoleCP(uint numcp) и SetConsoleOutputCP(uint numcp), где numcp — номер кодовой страницы потоков ввода и вывода соответственно. Подробнее здесь: Console Functions — Windows Console | Microsoft Docs. Пример применения консольных функций WInAPI можно посмотреть в тестовом приложении под катом выше.

Совет 7. Обязательный и повторный! Функции SetConsoleCP должны размещаться в коде до первого оператора ввода-вывода в консоль.

Стратегия локализации приложения в консоли

  1. Удалить приложение PowerShell (если установлено), сохранив Windows PowerShell;

  2. Установить в качестве кодовую страницу консоли по умолчанию CP65001 (utf-8 Unicode) или CP1251 (Windows-1251-Cyr), см. совет 5;

  3. Разработку приложений выполнять в кодировке utf-8 Unicode;

  4. Контролировать кодировку файлов исходных кодов, текстовых файлов данных, например с помощью Notepad++;

  5. Реализовать программное управление локализацией приложения в консоли, пример ниже под катом:

Пример программной установки кодовой страницы и локализации приложения в консоли

using System;
using System.Runtime.InteropServices;

namespace LoggingConsole.Test
{
    partial class Program
    {
      	static void Main(string[] args)
        {
          	[DllImport("kernel32.dll")] static extern bool SetConsoleCP(uint pagenum);
        		[DllImport("kernel32.dll")] static extern bool SetConsoleOutputCP(uint pagenum);
            SetConsoleCP(65001);        //установка кодовой страницы utf-8 (Unicode) для вводного потока
            SetConsoleOutputCP(65001);  //установка кодовой страницы utf-8 (Unicode) для выводного потока
 
            Console.WriteLine($"Hello, World!");
        }
    }
}

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

К примеру, если мы напишем такой код на С++

То после компиляции, вот что будет выдавать нам консольное окно программы.

Если же мы будем использовать функцию setlocale() внутри функции main()

То получим вместо иероглифов нормальный русский шрифт, вуаля:

Также, можно опустить последний аргумент функции — setlocale(LC_ALL, «Russian»); можно заменить на setlocale(0, «»); — работоспособность программы от этого не изменится.

Как подключить русский язык в c

При использовании кириллических символов мы можем столкнуться с ситуацией, когда вместо кириллических символов отображаются непонятные знаки. Особенно это актуально для ОС Windows. И в этом случае необходимо явным образом задать текущую локаль (культуру) для вывода символов. В Си это делается с помощью функции setlocale() , определение которой имеется в заголовочном файле locale.h .

Итак, изменим код, который использовался в прошлых темах следующим образом:

Компиляция и запуск в ОС Windows может выглядеть следующим образом:

Русский язык в Си в консоли

Вместо русских слов я получаю непонятные символы, и это не то, что ожидалось. Теперь изменим код, применив функцию setlocale:

Поскольку функция setlocale определена в файле locale.h, то он подключается с помощью директивы #include <locale.h> .

Повторно компилируем и запустим приложение:

Кириллица в консоли в Си

Стоит отметить, что в качестве кодировки текстового файла в этом случае должна использоваться кодировка ANSI или Windows-1251, но не UTF-8.

На некоторых платформах, например, Ubuntu 16.04, мы можем не столкнуться с подобной проблемой. И в этом случае вызов функции setlocale просто не окажет никакого влияния.

setlocale , _wsetlocale

Устанавливает или извлекает языковой стандарт времени выполнения.

Синтаксис

Параметры

category
Категория, на которую влияет языковой стандарт.

locale
Указатель языкового стандарта.

Возвращаемое значение

Если даны действительные locale и category , возвращает указатель на строку, связанную с указанным locale и category .

Если недопустимый locale или category недопустимый обработчик параметров, вызывается обработчик недопустимых параметров, как описано в разделе «Проверка параметров». Если выполнение может быть продолжено, эта функция задает для errno значение EINVAL и возвращает NULL .

задает все категории, возвращая только строку

Можно скопировать строку, возвращенную setlocale , для восстановления этой части данных о языковом стандарте программы. Глобальное или локальное хранилище потока используется для строки, возвращаемой setlocale . Последующие вызовы setlocale перезаписывают эту строку, что аннулирует указатели строк, возвращенные предыдущими вызовами.

Remarks

Используйте функцию setlocale для задания, изменения или получения некоторой или всей информации о языковом стандарте текущей программы, определяемой locale и category . locale ссылается на расположение (страну или регион и язык), для которого можно настраивать определенные аспекты программы. К некоторым категориям, зависящим от языкового стандарта, относится формат дат и отображения денежных значений. Если для locale задается строка по умолчанию для языка с несколькими формами, которые поддерживаются на вашем компьютере, необходимо проверять возвращаемое значение setlocale , чтобы узнать, какой язык применяется. Например, если задано locale «chinese» возвращаемое значение, может быть либо «chinese-simplified» «chinese-traditional» .

_wsetlocale — это версия с расширенными символами для setlocale ; аргумент locale и возвращаемое значение _wsetlocale являются строками с расширенными символами. Поведение _wsetlocale и setlocale идентично в противном случае.

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

Универсальное текстовое сопоставление функций

TCHAR.H Обычной _UNICODE & _MBCS не определен _MBCS Определенные _UNICODE Определенные
_tsetlocale setlocale setlocale _wsetlocale

Аргумент category указывает части информации о языковом стандарте программы, которые подвергаются влиянию. Макросы, используемые для category и части программы, на которые они оказывают, указаны ниже.

флаг категории Область применения
LC_ALL Все категории, перечисленные ниже.
LC_COLLATE Функции strcoll , _stricoll , wcscoll , _wcsicoll , strxfrm , _strncoll , _strnicoll , _wcsncoll , _wcsnicoll и wcsxfrm .
LC_CTYPE Функции обработки символов (за исключением isdigit , isxdigit , mbstowcs и mbtowc , которые не затрагиваются).
LC_MONETARY Информация о форматировании денежных значений, возвращаемая функцией localeconv .
LC_NUMERIC Символ десятичного разделителя для информации процедур форматированного вывода (например, printf ), для процедур преобразования данных и для форматирования не относящихся к денежным значений, возвращаемой localeconv . Помимо символа десятичной запятой, LC_NUMERIC задает разделитель тысяч и строку элемента управления группировкой, возвращаемую localeconv .
LC_TIME Функции strftime и wcsftime .

Эта функция проверяет параметр категории. Если параметр категории не является одним из значений, заданных в предыдущей таблице, вызывается обработчик недопустимых параметров, как описано в разделе «Проверка параметров». Если выполнение может быть продолжено, эта функция задает для errno значение EINVAL и возвращает NULL .

Аргумент locale является указателем на строку, которая задает языковой стандарт. Дополнительные сведения о формате аргумента locale см. в разделе Строки имени языкового стандарта, языка и страны и региона. Если locale указывает на пустую строку, языковой стандарт соответствует исходной среде, определенной реализацией. Значение C задает минимальную подходящую ANSI среду для переноса C. Языковой стандарт C предполагает, что все типы данных char соответствуют 1 байту, а их значение всегда меньше 256.

При запуске программы выполняется эквивалент следующего оператора:

Аргумент locale может принимать имя языкового стандарта, строковую переменную с названием языка, строковую переменную с названием языка и код страны или региона, кодовую страницу или строковую переменную с названием языка, код страны или региона и кодовую страницу. Набор доступных имен языков, языков, кодов страны или региона и кодовых страниц включает все поддерживаемые api NLS Windows. Набор имен языкового стандарта, поддерживаемых setlocale в строках языкового стандарта, языков и стран и регионов. Набор строковых значений языка и страны или региона, поддерживаемых setlocale , представлен в разделах Строки языка и Строки страны или региона. Рекомендуется использовать форму имени языкового стандарта для обеспечения производительности и удобства поддержки строк языкового стандарта, внедренных в код или сериализованных в хранилище. Строковые значения имен языкового стандарта реже подвергаются изменению обновлением операционной системы, чем язык и форма названия страны или региона.

Указатель null, который передается в качестве аргумента locale , указывает setlocale выполнить запрос, а не задать международную среду. locale Если аргумент является пустым указателем, текущий языковой стандарт программы не изменяется. Вместо этого setlocale возвращает указатель на строку, связанную с category текущего языкового стандарта этого потока. Если аргумент category имеет значение LC_ALL , функция возвращает строку, которая указывает текущий параметр каждой категории с разделением точкой с запятой. Например, последовательность вызовов

и это строка, связанная с категорией LC_ALL .

Следующие примеры относятся к категории LC_ALL . Любая из строк «. OCP» и «. ACP» можно использовать вместо номера кодовой страницы, чтобы указать использование пользовательской кодовой страницы OEM и кодовой страницы ANSI по умолчанию для этого имени языкового стандарта соответственно.

Задает языковой стандарт по умолчанию, т.е. заданную по умолчанию для пользователя кодовую страницу ANSI, полученную от операционной системы. Имя языкового стандарта задается значением GetUserDefaultLocaleName , возвращаемым . Кодовая страница имеет значение, возвращаемое GetACP .

Задает языковой стандарт для текущей кодовой страницы OEM, полученной из операционной системы. Имя языкового стандарта задается значением GetUserDefaultLocaleName , возвращаемым . Кодовая страница имеет LOCALE_IDEFAULTCODEPAGE значение для имени языкового стандарта пользователя по умолчанию. GetLocaleInfoEx

Задает языковой стандарт согласно текущей кодовой странице ANSI, полученной от операционной системы. Имя языкового стандарта задается значением GetUserDefaultLocaleName , возвращаемым . Кодовая страница имеет LOCALE_IDEFAULTANSICODEPAGE значение для имени языкового стандарта пользователя по умолчанию. GetLocaleInfoEx

Задает языковой стандарт для имени языкового стандарта, указанного в параметре <localename> . Кодовая страница имеет LOCALE_IDEFAULTANSICODEPAGE значение для указанного имени языкового стандарта по GetLocaleInfoEx .

Задает языковой стандарт для языка и страны или региона, указанных <language> и <country> вместе с кодовой страницей по умолчанию, полученной из операционной системы узла. Кодовая страница имеет LOCALE_IDEFAULTANSICODEPAGE значение для указанного имени языкового стандарта по GetLocaleInfoEx .

Задает языковой стандарт для языка, страны или региона и кодовой страницы, указанной <language> <country> строками и <code_page> строками. Можно использовать различные сочетания языка, страны или региона и кодовой страницы. Например, этот вызов устанавливает языковой стандарт «французский (Канада)» с кодовой страницей 1252.

setlocale( LC_ALL, «French_Canada.1252» );

Этот вызов устанавливает языковой стандарт «французский (Канада)» с кодовой страницей по умолчанию ANSI.

setlocale( LC_ALL, «French_Canada.ACP» );

Этот вызов устанавливает языковой стандарт «французский (Канада)» с кодовой страницей по умолчанию OEM.

setlocale( LC_ALL, «French_Canada.OCP» );

Задает языковой стандарт для языка, указанного <language> в этом языке, и использует страну или регион по умолчанию для указанного языка и кодовую страницу ANSI пользователя для этой страны или региона, полученной из операционной системы узла. Например, следующие вызовы setlocale функционально эквивалентны:

setlocale( LC_ALL, «English» );

setlocale( LC_ALL, «English_United States.1252» );

Рекомендуется использовать первую форму для обеспечения производительности и простоты обслуживания.

Задает кодовую страницу значения, указанного вместе с страной или регионом по умолчанию и языком <code_page> (как определено операционной системой узла) для указанной кодовой страницы.

Эта категория должна быть LC_ALL или LC_CTYPE для реализации изменения кодовой страницы. Например, если страна или регион по умолчанию и язык операционной системы узла имеют значение » United States » и » English «, следующие два вызова setlocale функционально эквивалентны:

setlocale( LC_ALL, «English_United States.1252»);

Дополнительные сведения см. в директиве setlocale pragma в справочнике по препроцессору C/C++.

Функция _configthreadlocale используется для управления тем, влияет ли setlocale языковой стандарт всех потоков в программе или только языковой стандарт вызывающего потока.

Поддержка UTF-8

Начиная с Windows 10 версии 1803 (10.0.17134.0), универсальная среда выполнения C поддерживает использование кодовой страницы UTF-8. Это означает, что строки, передаваемые в функции среды выполнения C, char будут ожидать строки в кодировке UTF-8. Чтобы включить режим UTF-8, используйте «.UTF8» в качестве кодовой страницы при использовании setlocale . Например, setlocale(LC_ALL, «.UTF8») будет использоваться текущая стандартная Windows кодовая страница ANSI (ACP) для языкового стандарта и UTF-8 для кодовой страницы.

Строка для указания режима UTF-8:

  • Не учитывает регистр.
  • дефис ( — ) является необязательным
  • Он должен находиться в части кодовой страницы имени языкового стандарта, поэтому должен иметь ведущий период ( . ), как в следующих примерах: «en_US.UTF8» «.utf8»

В следующих примерах показано, как указать строку UTF-8:

После вызова setlocale(LC_ALL, «.UTF8») вы можете передать «» mbtowcs и правильно преобразовать wchar_t его в строку, в то время как ранее для этого не был доступен параметр языкового стандарта.

Режим UTF-8 также включен для функций, которые имеют исторически переведенные char строки с помощью стандартной Windows кодовой странице ANSI (ACP). Например, вызов кодовой _mkdir(«») страницы UTF-8 будет правильно создавать каталог с этим эмодзи в качестве имени папки, а не требовать изменения ACP на UTF-8 перед запуском программы. Аналогичным образом вызов _getcwd() в этой папке вернет строку в кодировке UTF-8. Для обеспечения совместимости ACP по-прежнему используется, если кодовая страница C не имеет значения UTF-8.

Следующие аспекты среды выполнения C не могут использовать UTF-8, поскольку они задаются во время запуска программы и должны использовать кодовую страницу ANSI по умолчанию Windows ANSI: __argv _acmdln и _pgmptr .

Ранее эта поддержка, mbrtoc16 , mbrtoc32 , c16rtomb и c32rtomb существовала для преобразования между узкими строками UTF-8, UTF-16 (то же кодировка, что wchar_t и на платформах Windows) и UTF-32. По соображениям совместимости эти API-интерфейсы по-прежнему преобразуют только в UTF-8, а не с кодовой страницы. setlocale

Чтобы использовать эту функцию в ОС до Windows 10, необходимо использовать локальное развертывание приложения или связать статически с помощью версии 1803 (10.0.17134.0) пакета SDK Windows или более поздней версии. Для операционных систем Windows 10 до версии 1803 (10.0.17134.0) поддерживается только статическое связывание.

  • Remove From My Forums
  • Вопрос

  • После сохранения вводимой строки в массив, хочу ее снова вывести в строку, пишет иероглифы вместо русских букв. Облазил много сайтов и толком полезной информации не нашел, Windows form Visial Studio 2010. Пробовал через System::Text::Encoding::GetEncoding(1251));
    не получилось. Помогите, пожалуйста, второй день мучаюсь.

Ответы

  • У вас очень много проблем с этим кодом, от языка (C++/CLI который вообще не следует использовать для программирования) до самопального «шифрования» (тоже никогда не следует делать). 

    Но проблема «русских букв» заключена в том что вы теряйте половину данных «срезая» старший байт в 16 битных символах. Так что работает оно только для тех символов где этот байт нулевой. И он не нулевой для кириллицы. 

    В общем, замените все char (в первом массиве и везде где данные используются) на short (или int) и если ваш алгоритм «шифрования» работает для данных такого размера то русские буквы должны появится. 


    This posting is provided «AS IS» with no warranties, and confers no rights.

    • Помечено в качестве ответа

      3 октября 2017 г. 6:17

9 января 2018

Время чтения: 2 минуты

Превью к статье о том, как исправить русский язык в visual studio

При написании программ в среде Visual studio иногда возникает необходимость вывода текста на русском языке. Казалось бы, что тут сложного? Берёшь и выводишь! А вот нет, иначе бы не было кучи форумов и страничек в интернете с этой проблемой.
А проблема заключается в кодировке, причём все сайты пишут работающие способы, но, к сожалению, далеко не у всех. В этой статье мы расскажем вам о том, как действительно нужно исправлять эту проблему.

Итак, вы написали программу, в которой решили вывести строку русскими буквами, например, «Русский язык в консоли!». Вы запускаете программу, но вместо заветной строки видите там «кракозябры»! Что же делать?

#include <iostream>

int main() {
	std::cout << "Русский язык в консоли!" << std::endl;
	getchar();
	return 0;
}

Программа, выводящая русскую строку в visual studio

В результате видим кракозябры

В результате видим кракозябры

Чаще всего пишут, что достаточно лишь добавить setlocale(LC_ALL, "Russian"); в начале программы (для C программ требуется подключение библиотеки locale.h: #include <locale.h>). Сделаем это. Теперь программа должна выглядеть так:

#include <iostream>
#include <locale.h>

int main() {
	setlocale(LC_ALL, "Russian");
	std::cout << "Русский язык в консоли!" << std::endl;
	getchar();
	return 0;
}

Программа, выводящая русскую строку в visual studio

А возможный результат может выглядеть так:

Результат может быть как корректным, так и кракозябристым

Результат может быть как корректным, так и кракозябристым

Запустим её, если русский язык уже выводится — поздравляем! Проблема решена! Если нет, то идём дальше.

В верхнем меню выберете пункт файл, Сохранить <название вашего файла> как. В открывшемся окне вместо Сохранить выберем Сохранить с кодировкой, подтвердим, что желаем заменить файлы и выберем кодировку Кириллица (Windows) - кодовая страница 1251.

Сохраняем файл в другой кодировке

Сохраняем файл в другой кодировке

Выбираем сохранение с кодировкой

Выбираем сохранение с кодировкой

Выбираем кодировку Кириллица (Windows) - кодовая страница 1251

Выбираем кодировку Кириллица (Windows) — кодовая страница 1251

Нажмём ОК и соберём программу заново.

Нужная кодировка - Кириллица (Windows) - кодовая страница 1251

Нужная кодировка — Кириллица (Windows) — кодовая страница 1251

Запустим программу вновь и теперь русский язык будет корректно выводиться!

Программа запустилась и русский язык выводится

Программа запустилась и русский язык выводится

UPD: Ещё один способ заставить работать русский язык

Если ничего из вышеперечисленного не помогло, значит проблема в кодировке самой консоли. А её можно изменить с помощью команды system("chcp 1251");, то есть программа будет выглядеть так:

#include <iostream>
#include <locale.h>
#include <cstdlib>

int main() {
	setlocale(LC_ALL, "Russian"); // задаём русский текст
	system("chcp 1251"); // настраиваем кодировку консоли
	std::cout << "Русский язык в консоли!" << std::endl;
	getchar();
	return 0;
}

Фото Перминова Андрея, автора этой статьи

Программист, сооснователь programforyou.ru, в постоянном поиске новых задач и алгоритмов

Языки программирования: Python, C, C++, Pascal, C#, Javascript

Выпускник МГУ им. М.В. Ломоносова

Понравилась статья? Поделить с друзьями:
  • Подключение роутера vpn к windows 7
  • Подключение роутера tp link к компьютеру через кабель для windows 10
  • Подключение разорвано мтс коннект windows 10 как исправить
  • Подключение нового жесткого диска windows 10 не видит
  • Подключение нового жесткого диска ssd windows 10