вторник, 9 апреля 2013 г.

Локализация вывода в программах на языке C

При создании программы на языке С с использованием стандартного типа char и функций стандартного ввода/вывода типа printf мы пользуемся старинным подходом, идущим ещё от K&R и C89, основанном на представлением символов в кодировке ASCII (8-битной). Данный подход часто приводит к жалобам типа "А у меня по-русски в консоли не пишет... " и заставляет использовать многочисленные способы русификации консоли.

Рассмотрим некоторые возможные решения.

Во-первых, нужно рекомендовать к использованию стандартный механизм локализации, работающий в любой нормальной ОС

#include <locale.h >
...
int main()
{
   setlocale(LC_ALL,"");
   ...
   return 0;
}

С помощью функции setlocale мы настраиваем параметры локализации, принятые в нашей системе по-умолчанию (пустые кавычки), или мы можем настроить на работу с желаемой локалью, указав в кавычках желаемый язык и кодировку.

Во-вторых, в Windows до сих пор применяется старое-престарое решение с перекодировкой символов из 1251 в 866:

#include <windows.h >
...
int main()
{
   char str[]="Привет всем!";
   CharToOem(str,str);
   printf("%s\n",str);
   return 0;
}

В-третьих, для той же Windows существует ещё одно, более современное решение:

#include <windows.h >
..
int main()
{
   char str[]="Привет всем!";
   SetConsoleCP(1251);
   SetConsoleOutputCP(1251); 
   printf("%s\n",str);
   return 0;
}

Для корректного отображения кириллицы нужно выставить отображение TrueType шрифтов в свойстве окна windows-терминала (cmd).

И, наконец, четвёртое, универсальное решение, работающее во всех системах и основанное на поддержке юникода, размещаемого в стандартном (C99) типе wchar_t:

#include <wchar.h >
#include <stdio.h >
#include <locale.h >
int main()
{
   wchar_t str[]=L"Привет всем!";
   setlocale(LC_ALL,"");
   wprintf(L"%ls\n",str);
   return 0;
}

Мы использовали тип wchar_t для хранения многобайтных (расширенных) символов, специальный модификатор для поддержки Юникода L перед строковыми константами, а также функцию wprintf с полем типа %ls (юникодовская строка).

Благодаря типу wchar_t удаётся "подружить" консольное приложение с русским (и не только) языком.



Комментариев нет:

Отправить комментарий