Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Настройка локали
При изменении регистра русских букв может возникнуть проблема. Чтобы ее избежать, необходимо правильно настроить локаль (совокупность локальных настроек системы).
Настройка локали в языке C
Для настройки локали используется функция setlocale()
. Прототип функции:
#include <clocale> /* или #include <locale.h> */
char *setlocale(int category, const char *locale);
В первом параметре указывается категория в виде числа от 0
до 5
или соответствующий числу макрос:
0
—LC_ALL
— устанавливает локаль для всех категорий;1
—LC_COLLATE
— для сравнения строк;2
—LC_CTYPE
— для перевода символов в нижний или верхний регистр;3
—LC_MONETARY
— для отображения денежных единиц;4
—LC_NUMERIC
— для форматирования дробных чисел;5
—LC_TIME
— для форматирования вывода даты и времени.
Во втором параметре задается название локали в виде строки, например: rus
, russian
или Russian_Russia
. В этом случае будет задана кодировка, используемая в системе по умолчанию:
char *pLocale = std::setlocale(LC_ALL, "Russian_Russia");
if (pLocale) {
std::cout << pLocale << std::endl; // Russian_Russia.1251
}
else std::cout << "Не удалось настроить локаль" << std::endl;
Чтобы использовать другую кодировку нужно указать ее название после точки, например, ".1251"
или "Russian_Russia.1251"
:
char *pLocale = std::setlocale(LC_ALL, "Russian_Russia.1251");
if (pLocale) {
std::cout << pLocale << std::endl; // Russian_Russia.1251
}
else std::cout << "Не удалось настроить локаль" << std::endl;
Вместо названия можно указать пустую строку. В этом случае будет использоваться локаль, настроенная в системе:
char *pLocale = std::setlocale(LC_ALL, "");
if (pLocale) {
std::cout << pLocale << std::endl; // Russian_Russia.1251
}
В качестве значения функция возвращает указатель на строку с названием локали, соответствующей заданной категории, или нулевой указатель в случае ошибки. Если во втором параметре передан нулевой указатель, то функция возвращает указатель на строку с названием текущей локали:
char *pLocale = std::setlocale(LC_ALL, nullptr);
if (pLocale) {
std::cout << pLocale << std::endl; // C
}
Для настройки локали можно также использовать функцию _wsetlocale()
. Прототип функции:
#include <cwchar> /* или #include <wchar.h> */
wchar_t *_wsetlocale(int category, const wchar_t *locale);
Параметры аналогичны одноименным параметрам функции setlocale()
, но во втором параметре указывается L-строка с названием локали и возвращается указатель на L-строку:
wchar_t *pLocale = _wsetlocale(LC_ALL, L"Russian_Russia.1251");
if (pLocale) {
std::wcout << pLocale << std::endl; // Russian_Russia.1251
}
После настройки локали многие функции будут работать не так как раньше. Например, от настроек локали зависит вывод функции printf()
:
std::printf("%.2f\n", 2.5); // 2.50
std::setlocale(LC_NUMERIC, "dutch");
std::printf("%.2f\n", 2.5); // 2,50
Некоторые функции позволяют указать локаль в качестве параметра, например, функция _printf_l()
:
int _printf_l(const char *format, _locale_t locale, ...);
Во втором параметре функция принимает структуру _locale_t
с настройками локали. Создать эту структуру позволяет функция _create_locale()
. Прототип функции:
#include <clocale> /* или #include <locale.h> */
_locale_t _create_locale(int category, const char *locale);
Все параметры аналогичны одноименным параметрам функции setlocale()
. Если структуру создать не удалось, то функция возвращает нулевой указатель.
Создать структуру _locale_t
с настройками текущей локали позволяет функция _get_current_locale()
. Прототип функции:
#include <clocale> /* или #include <locale.h> */
_locale_t _get_current_locale(void);
Когда структура больше не нужна, ее следует освободить с помощью функции _free_locale()
. Прототип функции:
#include <clocale> /* или #include <locale.h> */
void _free_locale(_locale_t locale);
Пример настройки локали и вывода текущего названия локали приведен в листинге 7.1.
Листинг 7.1. Настройка локали
#include <iostream>
#include <clocale>
int main() {
char *pLocale = std::setlocale(LC_ALL, NULL);
if (pLocale) {
std::cout << pLocale << std::endl; // C
}
std::printf("%.2f\n", 3.14); // 3.14
pLocale = std::setlocale(LC_NUMERIC, "dutch");
if (pLocale) {
std::cout << pLocale << std::endl; // Dutch_Netherlands.1252
}
std::printf("%.2f\n", 3.14); // 3,14
pLocale = std::setlocale(LC_ALL, "Russian_Russia");
if (pLocale) {
std::cout << pLocale << std::endl; // Russian_Russia.1251
}
pLocale = std::setlocale(LC_ALL, "Russian_Russia.866");
if (pLocale) {
std::cout << pLocale << std::endl; // Russian_Russia.866
}
_locale_t locale_c = _create_locale(LC_NUMERIC, "C");
_printf_l("%.2f\n", locale_c, 3.14); // 3.14
_free_locale(locale_c);
_locale_t locale_de = _create_locale(LC_NUMERIC, "dutch");
_printf_l("%.2f\n", locale_de, 3.14); // 3,14
_free_locale(locale_de);
return 0;
}
Функция localeconv()
позволяет получить информацию о способе форматирования вещественных чисел и денежных сумм для текущей локали. Прототип функции:
#include <clocale> /* или #include <locale.h> */
struct lconv *localeconv(void);
Функция возвращает указатель на структуру lconv
. Пример вывода символа десятичного разделителя для локали Russian_Russia.1251
:
std::setlocale(LC_ALL, "Russian_Russia.1251");
lconv *p = std::localeconv();
if (p) {
std::cout << p->decimal_point << std::endl;
}
Объявление структуры lconv
выглядит следующим образом:
struct lconv {
char *decimal_point; // Десятичный разделитель (",")
char *thousands_sep; // Разделитель тысяч (" ")
char *grouping; // Способ группировки значений
char *int_curr_symbol; // Название валюты ("RUR")
char *currency_symbol; // Символ валюты ("р.")
char *mon_decimal_point; // Десятичный разделитель для
// денежных сумм (",")
char *mon_thousands_sep; // Разделитель тысяч для денежных
// сумм (" ")
char *mon_grouping; // Способ группировки для денежных сумм
char *positive_sign; // Положительный знак для денежных сумм
char *negative_sign; // Отрицательный знак для денежных сумм ("-")
char int_frac_digits; // Количество цифр в дробной части для
// денежных сумм в международном формате (2)
char frac_digits; // Количество цифр в дробной части для
// денежных сумм в национальном формате (2)
char p_cs_precedes; // 1 - если символ валюты перед значением
// 0 - если символ валюты после значения
char p_sep_by_space; // 1 - если символ валюты отделяется пробелом
// 0 - в противном случае
// p_cs_precedes и p_sep_by_space применяются
// для положительных значений
char n_cs_precedes; // 1 - если символ валюты перед значением
// 0 - если символ валюты после значения
char n_sep_by_space; // 1 - если символ валюты отделяется пробелом
// 0 - в противном случае
// n_cs_precedes и n_sep_by_space применяются
// для отрицательных значений
char p_sign_posn; // Позиция символа положительного значения
char n_sign_posn; // Позиция символа отрицательного значения
};
В VC++ доступны также следующие поля структуры lconv
:
wchar_t *_W_decimal_point;
wchar_t *_W_thousands_sep;
wchar_t *_W_int_curr_symbol;
wchar_t *_W_currency_symbol;
wchar_t *_W_mon_decimal_point;
wchar_t *_W_mon_thousands_sep;
wchar_t *_W_positive_sign;
wchar_t *_W_negative_sign;
Помощь сайту
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов