Несмотря на то, что в стандартах языка C, поддерживающих POSIX, существуют средства работы с информацией о денежных суммах, в состав этих средств не входят функции преобразования их формата. Такая возможность предоставляется функцией XPG strfmon. Функций, преобразующих строки в формате денежных сумм в числовой формат, который допускает выполнение арифметических операций, не существует. Для выполнения такой операции в приложении можно преобразовать строку денежной суммы, заданную в соответствии с параметрами текущей локали, в число. Информация о формате национальных денежных единиц хранится в категории LC_MONETARY. Для передачи приложению информации о формате денежных сумм и символа национальной валюты служит функция localeconv.
Для определения формата представления денежных сумм в соответствии с национальными стандартами функция strfmon использует информацию из категории локали LC_MONETARY. С введением общеевропейской валюты Евро возникла потребность поддержки не только традиционных национальных валют, но и Евро. Для этой цели был веден модификатор @euro. В локаль каждого европейского государства, в котором имеет хождение Евро, добавлено определение LC_MONETARY с модификатором @euro. Этот альтернативный формат применяется, если он указан в переменной среды локали, а также в функции setlocale.
Для работы с французской локалью, кодовым набором UTF-8 и французским франком в качестве денежной единицы следует указать:
LANG=FR_FR
Для работы с французской локалью, кодовым набором UTF-8 и Евро в качестве денежной единицы следует указать:
LANG=FR_FR LC_MONETARY=FR_FR@euro
Не следует указывать LANG=FR_FR@euro, так как значение @euro для любой категории локали, отличной от LC_MONETARY, не определено.
#include <monetary.h> #include <locale.h> #include <stdio.h> main(int argc, char **argv) { char bfr[256], format[256]; int match; ssize_t size; float value; (void) setlocal(LC_ALL, ""); if (argc != 3){ ... /* Обработка ошибок */ } match = sscanf(argv[1], "%f", &value); if (!match) { ... /* Обработка ошибок */ } match = sscanf(argv[2], "%s", format); if (!match) { ... /* Обработка ошибок */ } size = strfmon(bfr, 256, format, value); if (size == -1) { ... /* Обработка ошибок */ } printf ("Значение денежной суммы: %s\n", bfr); }
В следующей таблице приведены примеры возможных спецификаций преобразования
и вывод для значений 12345.67 и -12345.67 при использовании
локали английского языка для США:
Спецификация преобразования | Вывод | Описание |
---|---|---|
%n | $12,345.67 -$12,345.67 | Форматирование по умолчанию |
%15n | $12,345.67 -$12,345.67 | Выравнивание по правому краю в поле из 15 позиций |
%#6n | $ 12,345.67 -$ 12,345.67 | Выравнивание колонки для значений до 999,999. |
%=*#8n | $****12,345.67 -$****12,345.67 | Применение символа заполнения. |
%=0#8n | $000012,345.67 -$000012,345.67 | Применение символов заполнения без группировки. |
%^#6n | $ 12345.67 -$ 12345.67 | Отмена разделителя разрядов. |
%^#6.0n | $ 12346 -$ 12346 | Округление до целого числа. |
%^#6.3n | $ 12345.670 -$ 12345.670 | Увеличение точности. |
%(#6n | $ 12,345.67 ($ 12,345.67) | Изменение способа обозначения отрицательных чисел. |
%!(#6n | 12,345.67 ( 12,345.67) | Отмена символа денежной единицы. |
char *input; /* многобайтовая входная строка, содержащая денежную сумму */ char *output; /* числовая строка, получаемая из строки ввода */ wchar_t src_string[SIZE], dest_string[SIZE]; wchar_t *monetary, *numeric; wchar_t mon_decimal_point, radixchar; wchar_t wc; localeconv *lc; /* Инициализировать input и output. */ /* Преобразовать входную строку */ retval = mbstowcs(src_string, input, SIZE); /* Обработать возврат по ошибке */ monetary = src_string; numeric = dest_string; lc = localeconv(); /* получить информацию LC_MONETARY и LC_NUMERIC */ /* Преобразовать десятичное значение денежной суммы в формат широких символов */ retval = mbtowc( &mon_decimal_point, lc->mon_decimal_point, MB_CUR_MAX); /* Обработка ошибок */ /* Преобразовать числовое десятичное значение в формат широких символов */ retval = mbtowc( &radixchar, lc->decimal_point, MB_CUR_MAX); /* Обрабатывать возможную ошибку */ /* monetary указывает на строку, предварительно преобразованную в формат ** широких символов с помощью mbstowcs. */ /* Получить числовую информацию из строки широких символов ** и скопировать во временный буфер. */ while(wc = *monetary++){ if(iswdigit(wc)) *numeric++ = wc; else if( wc == mon_decimal_point) *numeric++=radixchar; } *numeric = 0; /* dest_string получает числовое значение денежной величины. */ /* Преобразовать числовую величину в многобайтовый формат */ retval = wcstombs( output, dest_string, SIZE); /* Обработать все возвраты по ошибке */ /* Вывод содержит числовое значение, пригодное для преобразования atof */
В разделе Функции для поддержки национальных языков - Обзор приведены дополнительные сведения о функциях обработки широких и многобайтовых символов.
Общие сведения о локализации программ приведены в разделах Поддержка национальных языков в программировании - Введение (Глава 16, Поддержка национальных языков) и Локаль - Информация для программистов.
Функция strfmon.