char int_p_sign_posn;
char int_n_sign_posn;
};
Комментарии показывают довольно ясно, что происходит. Давайте посмотрим на несколько первых полей
struct lconv
:
decimal_point
Используемый символ разделителя десятичной дроби. В Соединенных Штатах и других англоязычных странах это точка, но во многих странах используется запятая.
thousands_sep
Символ, используемый для разделения каждых 3 цифр значения.
grouping
Массив однобайтных целых значений. Каждый элемент указывает, сколько цифр в группе. Как сказано в комментарии,
CHAR_MAX
означает, что дальше группировка не используется, а 0 означает повторное использование последнего элемента (Далее в главе мы покажем пример кода.)
int_curr_symbol
Это международный символ для местной валюты. Например, 'USD' для доллара США.
currency_symbol
Локальный символ для местной валюты. Например, $ для доллара США.
mon_decimal_point
,
mon_thousands_sep
,
mon_grouping
Соответствуют предыдущим полям, предоставляя те же сведения, но для денежных сумм.
Большая часть оставшихся значений не имеет значения для повседневного программирования. Следующая программа,
ch13-lconv.c
, выводит некоторые из этих значений, чтобы дать вам представление, для какого рода сведений они используются:
/* ch13-lconv.c --- показывает некоторые компоненты struct lconv */
#include <stdio.h>
#include <limits.h>
#include <locale.h>
int main(void) {
struct lconv l;
int i;
setlocale(LC_ALL, "");
l = *localeconv();
printf("decimal_point = [%s]\n", l.decimal_point);
printf("thousands_sep = [%s]\n", l.thousands_sep);
for (i = 0; l.grouping[i] != 0 && l.grouping[i] != CHAR_MAX; i++)
printf("grouping[%d] = [%dj\n", i, l.grouping[i]);
printf("int_curr_symbol = [%s]\n", l.int_curr_symbol);
printf("currency_symbol = f%s]\n", l.currency_symbol);
printf("mon_decimal_point = f%s]\n", l.mon_decimal_point);
printf("mon_thousands_sep = [%s]\n", l.mon_thousands_sep);
printf("positive_sign = [%s]\n", l.positive_sign);
printf("negative_sign = [%s]\n", l.negative_sign);
}
Неудивительно, при запуске в различных локалях мы получаем различные результаты.
$ <b>LC_ALL=en_US ch13-lconv</b> /* Результаты для Соединенных Штатов */
decimal_point = [.]
thousands_sep = [,]
grouping[0] = [3]
grouping[1] = [3]
int_curr_symbol = [USD ]
currency_symbol = [$]
mon_decimal_point = [.]
mon_thousands_sep = [,]
positive_sign = []
negative_sign = [-]
$ <b>LC_ALL=it_IT ch13-lconv</b> /* Результаты для Италии */
decimal_point = [.]
thousands_sep = []
int_curr_symbol = []
currency_symbol = []
mon_decimal_point = []
mon_thousands_sep = []
positive_sign = []
negative_sign = []
Обратите внимание, что значение
int_curr_symbol
в локали "
en_US
" включает завершающий символ пробела, который служит для отделения символа от последующего денежного значения.
13.2.5. Высокоуровневое числовое и денежное форматирование:
strfmon()
и printf()
После рассмотрения всех полей
struct lconv
вы можете поинтересоваться: «Нужно ли мне
на самом деле выяснять, как использовать все эти сведения, просто для форматирования денежного значения?» К счастью, ответом является «нет».
[140] Функция
strfmon()
делает за вас всю работу:
#include <monetary.h> /* POSIX */
ssize_t strfmon(char *s, size_t max, const char *format, ...);
Эта функция во многом подобна
strftime()
(см. раздел 6.1.3.2 «Сложное форматирование времени:
strftime()
»), используя
format
для копирования символов букв и форматированных числовых значений в
s
, помещая в нее не более max символов. Следующая простая программа,
ch13-strfmon.c
, демонстрирует работу
strfmon()
:
/* ch13-strfmon.c --- демонстрация strfmon() */
#include <stdio.h>
#include <locale.h>
#include <monetary.h>
int main(void) {
char buf[BUFSIZ];
double val = 1234.567;
setlocale(LC_ALL, "");
strfmon(buf, sizeof buf, "You owe me %n (%i)\n", val, val);