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

Требования Requirements

Подпрограмма Routine Обязательный заголовок Required header
setlocale setlocale
_wsetlocale _wsetlocale или or

Дополнительные сведения о совместимости см. в разделе Совместимость. For additional compatibility information, see Compatibility.

В соответствии с документацией, strftime() должен возвращать локализованные значения даты и времени (название месяцев и дней недели и т.д.), однако делает это лишь после явной установки локали:

Почему на русском начинает выводить только после переопределения локали, хотя до этого она и так была (‘ru_RU’, ‘UTF-8’) ? Более того, достаточно просто сделать resetlocale:

UTF-8 Support

Starting in Windows 10 build 17134 (April 2018 Update), the Universal C Runtime supports using a UTF-8 code page. This means that strings passed to C runtime functions will expect strings in the UTF-8 encoding. To enable UTF-8 mode, use «UTF-8» as the code page when using . For example, will use the current default Windows ANSI code page (ACP) for the locale and UTF-8 for the code page.

After calling , you may pass «» to and it will be properly translated to a string, whereas previously there was not a locale setting available to do this.

UTF-8 mode is also enabled for functions that have historically translated strings using the default Windows ANSI code page (ACP). For example, calling while using a UTF-8 code page will correctly produce a directory with that emoji as the folder name, instead of requiring the ACP to be changed to UTF-8 prior to running your program. Likewise, calling inside of that folder will return a UTF-8 encoded string. For compatibility, the ACP is still used if the C locale code page is not set to UTF-8.

The following aspects of the C Runtime that are not able to use UTF-8 because they are set during program startup and must use the default Windows ANSI code page (ACP): , , and .

Previous to this support, , , , and existed to translate between UTF-8 narrow strings, UTF-16 (same encoding as on Windows platforms) and UTF-32. For compatibility reasons, these APIs still only translate to and from UTF-8 and not the code page set via .

To use this feature on an OS prior to Windows 10, such as Windows 7, you must use or link statically using version 17134 of the Windows SDK or later. For Windows 10 operating systems prior to 17134, only static linking is supported.

COLOPHON top

       This page is part of release 5.08 of the Linux man-pages project.  A
       description of the project, information about reporting bugs, and the
       latest version of this page, can be found at
       https://www.kernel.org/doc/man-pages/.

GNU                              2017-09-15                     SETLOCALE(3)

Pages that refer to this page:
apropos(1), 
groffer(1), 
localedef(1), 
man(1), 
whatis(1), 
catclose(3), 
catgets(3), 
catopen(3), 
dcgettext(3), 
dgettext(3), 
dprintf(3), 
duplocale(3), 
ecvt(3), 
fcvt(3), 
fprintf(3), 
freelocale(3), 
fscanf(3), 
getdate(3), 
getdate_err(3), 
getdate_r(3), 
gettext(3), 
isalnum(3), 
isalnum_l(3), 
isalpha(3), 
isalpha_l(3), 
isascii(3), 
isascii_l(3), 
isblank(3), 
isblank_l(3), 
iscntrl(3), 
iscntrl_l(3), 
isdigit(3), 
isdigit_l(3), 
isgraph(3), 
isgraph_l(3), 
islower(3), 
islower_l(3), 
isprint(3), 
isprint_l(3), 
ispunct(3), 
ispunct_l(3), 
isspace(3), 
isspace_l(3), 
isupper(3), 
isupper_l(3), 
isxdigit(3), 
isxdigit_l(3), 
localeconv(3), 
newlocale(3), 
nl_langinfo(3), 
nl_langinfo_l(3), 
printf(3), 
rpmatch(3), 
scanf(3), 
snprintf(3), 
sprintf(3), 
sscanf(3), 
strcoll(3), 
strfmon(3), 
strfmon_l(3), 
strftime(3), 
strptime(3), 
strxfrm(3), 
tolower(3), 
tolower_l(3), 
toupper(3), 
toupper_l(3), 
uselocale(3), 
vdprintf(3), 
vfprintf(3), 
vfscanf(3), 
vprintf(3), 
vscanf(3), 
vsnprintf(3), 
vsprintf(3), 
vsscanf(3), 
locale(5), 
locale(7), 
unicode(7), 
utf-8(7), 
utf8(7), 
UTF-8(7), 
lsof(8)

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

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

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

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

Теперь, кодировка входных файлов компилятора. Компилятор Microsoft Visual Studio (по крайней мере, версии 2012 и 2013) компилирует исходники в однобайтных кодировках так, как будто бы они на самом деле в ANSI-кодировке, то есть для случая русской системы — CP1251. Это означает, что кодировка исходников в CP866 — неправильна

(Это важно, если вы используете -строки.) С другой стороны, если вы храните исходники в CP1251, то эти же исходники не будут нормально собираться на нерусской Windows. Поэтому стоит хранить исходники в Unicode (например, UTF-8)

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

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

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

Вам нужно для переключения режима консоли:

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

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

Поэтому такой код:

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

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

языковой стандарт:: operator! =locale::operator!=

Проверка двух языковых стандартов на неравенство.Tests two locales for inequality.

ПараметрыParameters

ПравильноrightОдин из языковых стандартов для проверки на неравенство.One of the locales to be tested for inequality.

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

Логическое значение, равное, Если языковые стандарты не являются копиями одного и того же языкового стандарта.A Boolean value that is if the locales aren’t copies of the same locale. Если языковые стандарты являются копиями одного и того же языкового стандарта.It’s if the locales are copies of the same locale.

RemarksRemarks

Два языковых стандарта равны, если они совпадают, если одна из них является копией другого или если они имеют одинаковые имена.Two locales are equal if they’re the same locale, if one is a copy of the other, or if they have identical names.

setlocale Example

/* Example using setlocale by TechOnTheNet.com */

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

int main(int argc, const char * argv[])
{
    /* Define a temporary variable */
    struct lconv *loc;

    /* Set the locale to the POSIX C environment */
    setlocale (LC_ALL, "C");

    /* Retrieve a pointer to the current locale */
    loc = localeconv();

    /* Display some of the locale settings */
    printf("Thousands Separator: %s\n", loc->thousands_sep);
    printf("Currency Symbol: %s\n", loc->currency_symbol);

    /* Set the locale to the environment default */
    setlocale (LC_ALL, "");

    /* Retrieve a pointer to the current locale */
    loc = localeconv();

    /* Display some of the locale settings */
    printf("Thousands Separator: %s\n", loc->thousands_sep);
    printf("Currency Symbol: %s\n", loc->currency_symbol);

    return 0;
}

When compiled and run on a machine in North America, this application will output:

Thousands Separator: 
Currency Symbol: 
Thousands Separator: ,
Currency Symbol: $

locale:: классическийlocale::classic

Данная статическая функция-член возвращает объект языкового стандарта, представляющий классический языковой стандарт C.The static member function returns a locale object that represents the classic C locale.

RemarksRemarks

Классический язык C — это языковой стандарт ASCII американского английского языка в стандартной библиотеке C.The classic C locale is the U.S. English ASCII locale within the Standard C library. Это языковой стандарт, который неявно используется в программах, которые не являются международными.It’s the locale that’s used implicitly in programs that aren’t internationalized.

Syntax

The syntax for the setlocale function in the C Language is:

char *setlocale(int category, const char *locale);

Parameters or Arguments

category
The program’s locale to change. It can either be one category or all categories.
locale
A pointer to a string which contains the new locale.

Note

  • If category is LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, or LC_TIME macro, the setlocale function will only update one category.
  • If category is LC_ALL, the setlocale function will update all categories.

Returns

If locale is a null pointer, the setlocale function returns a pointer to the string associated with category for the current locale. If the locale is not a null pointer, the setlocale function returns a pointer to the string associated with category for the new locale.

If the setlocale function fails, a null pointer will be returned.

In the C Language, the required header for the setlocale function is:

#include <locale.h>

In the C Language, the setlocale function can be used in the following versions:

ANSI/ISO 9899-1990

setlocale Example

/* Example using setlocale by TechOnTheNet.com */

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

int main(int argc, const char * argv[])
{
    /* Define a temporary variable */
    struct lconv *loc;

    /* Set the locale to the POSIX C environment */
    setlocale (LC_ALL, "C");

    /* Retrieve a pointer to the current locale */
    loc = localeconv();

    /* Display some of the locale settings */
    printf("Thousands Separator: %s\n", loc->thousands_sep);
    printf("Currency Symbol: %s\n", loc->currency_symbol);

    /* Set the locale to the environment default */
    setlocale (LC_ALL, "");

    /* Retrieve a pointer to the current locale */
    loc = localeconv();

    /* Display some of the locale settings */
    printf("Thousands Separator: %s\n", loc->thousands_sep);
    printf("Currency Symbol: %s\n", loc->currency_symbol);

    return 0;
}

When compiled and run on a machine in North America, this application will output:

Thousands Separator: 
Currency Symbol: 
Thousands Separator: ,
Currency Symbol: $

Other C functions that are similar to the setlocale function:

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

Начиная с Windows 10 Build 17134 (обновление от апреля 2018), универсальная среда выполнения C поддерживает использование кодовой страницы UTF-8.Starting in Windows 10 build 17134 (April 2018 Update), the Universal C Runtime supports using a UTF-8 code page. Это означает, что строки, передаваемые в функции среды выполнения C, будут ждать строк в кодировке UTF-8.This means that strings passed to C runtime functions will expect strings in the UTF-8 encoding. Чтобы включить режим UTF-8, используйте «UTF-8» в качестве кодовой страницы при использовании .To enable UTF-8 mode, use «UTF-8» as the code page when using . Например, будет использовать текущую кодовую страницу ANSI Windows (ACP) по умолчанию для языкового стандарта и кодировку UTF-8 для кодовой страницы.For example, will use the current default Windows ANSI code page (ACP) for the locale and UTF-8 for the code page.

После вызова вы можете передать » » в, и он будет правильно преобразован в строку, в то время как ранее для этого не существовал параметр языкового стандарта.After calling , you may pass «» to and it will be properly translated to a string, whereas previously there was not a locale setting available to do this.

Режим UTF-8 также включается для функций с историческим переводом строк с помощью кодовой страницы Windows ANSI по умолчанию (ACP).UTF-8 mode is also enabled for functions that have historically translated strings using the default Windows ANSI code page (ACP). Например, вызов при использовании кодовой страницы UTF-8 правильно создаст каталог с этим символом эмодзи в качестве имени папки, а не требует, чтобы ACP был изменен на UTF-8 перед запуском программы.For example, calling while using a UTF-8 code page will correctly produce a directory with that emoji as the folder name, instead of requiring the ACP to be changed to UTF-8 prior to running your program. Аналогичным образом, вызов внутри этой папки вернет строку в кодировке UTF-8.Likewise, calling inside of that folder will return a UTF-8 encoded string. Для обеспечения совместимости ACP по-прежнему используется, если кодовая страница языка C не имеет значение UTF-8.For compatibility, the ACP is still used if the C locale code page is not set to UTF-8.

Следующие аспекты среды выполнения C не могут использовать кодировку UTF-8, так как они задаются во время запуска программы и должны использовать кодовую страницу ANSI Windows по умолчанию (ACP): , и .The following aspects of the C Runtime that are not able to use UTF-8 because they are set during program startup and must use the default Windows ANSI code page (ACP): , , and .

Предыдущая поддержка этой поддержки , ,, и существовала для преобразования между строками UTF-8, UTF-16 (то же кодирование, что и на платформах Windows) и UTF-32.Previous to this support, , , , and existed to translate between UTF-8 narrow strings, UTF-16 (same encoding as on Windows platforms) and UTF-32. По соображениям совместимости эти API-интерфейсы переводятся только в кодировку UTF-8 и не задаются кодовой страницей с помощью .For compatibility reasons, these APIs still only translate to and from UTF-8 and not the code page set via .

Чтобы использовать эту функцию в ОС до Windows 10, например Windows 7, необходимо использовать или компоновку, используя версию 17134 Windows SDK или более позднюю.To use this feature on an OS prior to Windows 10, such as Windows 7, you must use or link statically using version 17134 of the Windows SDK or later. Для операционных систем Windows 10 до 17134 поддерживается только статическая компоновка.For Windows 10 operating systems prior to 17134, only static linking is supported.

UTF-8 のサポートUTF-8 Support

Windows 10 ビルド 17134 (4 月2018更新プログラム) 以降では、ユニバーサル C ランタイムは UTF-8 コードページの使用をサポートしています。Starting in Windows 10 build 17134 (April 2018 Update), the Universal C Runtime supports using a UTF-8 code page. これは、 C ランタイム関数に渡される文字列では、utf-8 エンコーディングで文字列が想定されることを意味します。This means that strings passed to C runtime functions will expect strings in the UTF-8 encoding. UTF-8 モードを有効にするには、を使用するときにコードページとして «UTF-8» を使用し ます。To enable UTF-8 mode, use «UTF-8» as the code page when using . たとえば、 は、現在の既定の WINDOWS ANSI コードページ (ACP) をロケールに、utf-8 をコードページに使用します。For example, will use the current default Windows ANSI code page (ACP) for the locale and UTF-8 for the code page.

を呼び出す と、» » がに渡され、 文字列に適切に変換され ます。これに対して、以前はロケールの設定は使用できませんでした。After calling , you may pass «» to and it will be properly translated to a string, whereas previously there was not a locale setting available to do this.

UTF-8 モードは 、既定の WINDOWS ANSI コードページ (ACP) を使用して、以前に翻訳された文字列を含む関数に対しても有効です。UTF-8 mode is also enabled for functions that have historically translated strings using the default Windows ANSI code page (ACP). たとえば、 utf-8 コードページを使用してを呼び出すと、プログラムを実行する前に ACP を utf-8 に変更する必要がなく、フォルダー名としてその絵文字を持つディレクトリが正しく生成されます。For example, calling while using a UTF-8 code page will correctly produce a directory with that emoji as the folder name, instead of requiring the ACP to be changed to UTF-8 prior to running your program. 同様に、 そのフォルダー内でを呼び出すと、utf-8 でエンコードされた文字列が返されます。Likewise, calling inside of that folder will return a UTF-8 encoded string. 互換性のために、C ロケールのコードページが UTF-8 に設定されていない場合でも、ACP は引き続き使用されます。For compatibility, the ACP is still used if the C locale code page is not set to UTF-8.

UTF-8 を使用できない C ランタイムの次の側面は、プログラムの起動中に設定されており、既定の Windows ANSI コードページ (ACP) を使用する必要があるためです。 The following aspects of the C Runtime that are not able to use UTF-8 because they are set during program startup and must use the default Windows ANSI code page (ACP): , , and .

以前のバージョンでは、、、 、 および は、utf-8のナロー文字列、utf-16 (Windows プラットフォームと同じエンコード)、 および 32 utf-8 を変換するために存在していました。Previous to this support, , , , and existed to translate between UTF-8 narrow strings, UTF-16 (same encoding as on Windows platforms) and UTF-32. 互換性上の理由から、これらの Api は、によって設定されたコードページではなく、UTF-8 との間でのみ変換を行い ます。For compatibility reasons, these APIs still only translate to and from UTF-8 and not the code page set via .

Windows 7 などの Windows 10 より前の OS でこの機能を使用するには、を使用するか、Windows SDK 以降のバージョン17134を使用して静的にリンクする必要があります。To use this feature on an OS prior to Windows 10, such as Windows 7, you must use or link statically using version 17134 of the Windows SDK or later. 17134より前の Windows 10 オペレーティングシステムでは、静的リンクのみがサポートされています。For Windows 10 operating systems prior to 17134, only static linking is supported.

UTF-8 支持UTF-8 Support

从 Windows 10 build 17134 开始 (2018 年4月更新) ,通用 C 运行时支持使用 UTF-8 代码页。Starting in Windows 10 build 17134 (April 2018 Update), the Universal C Runtime supports using a UTF-8 code page. 这意味着 传递给 C 运行时函数的字符串将需要 utf-8 编码格式的字符串。This means that strings passed to C runtime functions will expect strings in the UTF-8 encoding. 若要启用 UTF-8 模式,请在使用时使用 «UTF-8» 作为代码页 。To enable UTF-8 mode, use «UTF-8» as the code page when using . 例如, 将使用当前默认 WINDOWS ANSI 代码页 (ACP) 用于区域设置,并使用 utf-8 作为代码页。For example, will use the current default Windows ANSI code page (ACP) for the locale and UTF-8 for the code page.

调用后 ,你可以将 «» 传递给, 并将其正确地转换为 字符串,但之前没有可用于执行此操作的区域设置。After calling , you may pass «» to and it will be properly translated to a string, whereas previously there was not a locale setting available to do this.

对于 使用默认 WINDOWS ANSI 代码页( (ACP) )的已翻译字符串,也启用了 utf-8 模式。UTF-8 mode is also enabled for functions that have historically translated strings using the default Windows ANSI code page (ACP). 例如, 当使用 utf-8 代码页时,调用会正确生成包含该表情符号作为文件夹名称的目录,而不需要在运行程序之前将 ACP 更改为 utf-8。For example, calling while using a UTF-8 code page will correctly produce a directory with that emoji as the folder name, instead of requiring the ACP to be changed to UTF-8 prior to running your program. 同样, 在该文件夹内调用将返回 utf-8 编码的字符串。Likewise, calling inside of that folder will return a UTF-8 encoded string. 为实现兼容性,如果 C 区域设置代码页未设置为 UTF-8,则仍将使用 ACP。For compatibility, the ACP is still used if the C locale code page is not set to UTF-8.

C 运行时的以下方面不能使用 utf-8,因为在程序启动过程中设置了 utf-8,并且必须使用默认的 Windows ANSI 代码页 (ACP) : 、 和 。The following aspects of the C Runtime that are not able to use UTF-8 because they are set during program startup and must use the default Windows ANSI code page (ACP): , , and .

之前,此支持、 、 、 和存在于 utf-8 窄字符串之间,utf-16 (与 Windows 平台上的相同编码) 和32。Previous to this support, , , , and existed to translate between UTF-8 narrow strings, UTF-16 (same encoding as on Windows platforms) and UTF-32. 出于兼容性原因,这些 Api 仍只能从 utf-8 转换到 utf-8,而不是通过设置代码页 。For compatibility reasons, these APIs still only translate to and from UTF-8 and not the code page set via .

若要在 Windows 10 之前的操作系统(如 Windows 7)上使用此功能,必须使用 Windows SDK 或更高版本的17134版的或静态链接。To use this feature on an OS prior to Windows 10, such as Windows 7, you must use or link statically using version 17134 of the Windows SDK or later. 对于17134之前的 Windows 10 操作系统,仅支持静态链接。For Windows 10 operating systems prior to 17134, only static linking is supported.

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

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

Adblock
detector