[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]

General Programming Concepts: Writing and Debugging Programs

Monetary Formatting Subroutines

Although the C programming language standard in conjunction with POSIX provides a means of specifying and accessing monetary information, these standards do not define a subroutine that formats monetary quantities. The XPG strfmon subroutine provides the facilities to format monetary quantities. There is no defined subroutine that converts a formatted monetary string into a numeric quantity suitable for arithmetic. Applications that need to do arithmetic on monetary quantities may do so after processing the locale-dependent monetary string into a number. The culture-specific monetary formatting information is specified by the LC_MONETARY category. An application can obtain information pertaining to the monetary format and the currency symbol by calling the localeconv subroutine.

Euro Currency Support via the @euro Modifier

The strfmon subroutine uses the information from the locale's LC_MONETARY category to determine the correct monetary format for the given language/territory. With the advent of the common European currency (Euro), locales must be able to handle both the traditional national currencies as well as the common European currency. This is accomplished via the @euro modifier. Each European country that uses the Euro will have an additional LC_MONETARY definition with the @euro modifier appended. This alternate format will be invoked when specified via the locale environment variables, or with the setlocale subroutine.

To use the French locale , UTF-8 codeset environment, and French francs as the monetary unit, simply set:


To use the French locale, UTF-8 codeset environment,and Euros as the monetary unit, set:


Users should NOT attempt to set LANG=FR_FR@euro, as the @euro variant for locale categories other than LC_MONETARY is undefined.


  1. The following example uses the strfmon subroutine and accepts a format specification and an input value. The input value is formatted according to the input format specification.

    #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){
                    ...        /* Error handling */
            match = sscanf(argv[1], "%f", &value);
            if (!match) {
                    ...        /* Error handling */
            match = sscanf(argv[2], "%s", format);
            if (!match) {
                    ...        /*Error handling */
            size = strfmon(bfr, 256, format, value);
            if (size == -1) {
                    ...        /* Error handling */
            printf ("Formatted monetary value is: %s\n", bfr);

    The following table provides examples of some of the possible conversion specifications and the outputs for 12345.67 and -12345.67 in a US English locale:

    Conversion Specification Output Description
    %n $12,345.67 -$12,345.67 Default formatting
    %15n $12,345.67 -$12,345.67 Right justifies within a 15-character field.
    %#6n $ 12,345.67 -$ 12,345.67 Aligns columns for values up to 999,999.
    %=*#8n $****12,345.67 -$****12,345.67 Specifies a fill character.
    %=0#8n $000012,345.67 -$000012,345.67 Fill characters do not use grouping.
    %^#6n $ 12345.67 -$ 12345.67 Disables the thousands separator.
    %^#6.0n $ 12346 -$ 12346 Rounds off to whole units.
    %^#6.3n $ 12345.670 -$ 12345.670 Increases the precision.
    %(#6n $ 12,345.67 ($ 12,345.67) Uses an alternate positive or negative style.
    %!(#6n 12,345.67 ( 12,345.67) Disables the currency symbol.
  2. The following example converts a monetary value into a numeric value. The monetary string is pointed to by input and the result of converting it into numeric form is stored in the string pointed to by output. Assume input and output are initialized.

    char *input;   /* the input multibyte string containing the monetary string */
    char *output;  /* the numeric string obtained from the input string */
    wchar_t src_string[SIZE], dest_string[SIZE];
    wchar_t *monetary, *numeric;
    wchar_t mon_decimal_point, radixchar;
    wchar_t wc;
    localeconv *lc;
    /* Initialize input and output to point to valid buffers as appropriate. */
    /* Convert the input string to process code form*/
    retval = mbstowcs(src_string, input, SIZE);
    /* Handle error returns */
    monetary = src_string;
    numeric = dest_string;
    lc = localeconv();
            /* obtain the LC_MONETARY and LC_NUMERIC info */
    /* Convert the monetary decimal point to wide char form */
    retval = mbtowc( &mon_decimal_point, lc->mon_decimal_point,
    /* Handle any error case */
    /* Convert the numeric decimal point to wide char form */
    retval = mbtowc( &radixchar, lc->decimal_point, MB_CUR_MAX);
    /* Handle error case */
    /* Assuming the string is converted first into wide character
    ** code form via mbstowcs, monetary points to this string.
    /* Pick up the numeric information from the wide character
    ** string and copy it into a temp buffer.
            while(wc = *monetary++){
                            *numeric++ = wc;
                    else if( wc == mon_decimal_point)
            *numeric = 0;
    /* dest_string has the numeric value of the monetary quantity. */
    /* Convert the numeric quantity into multibyte form */
    retval = wcstombs( output, dest_string, SIZE);
    /* Handle any error returns */
    /* Output contains a numeric value suitable for atof conversion. */ 

Related Information

National Language Support Subroutines Overview provides information about wide character and multibyte subroutines.

For general information about internationalizing programs, see National Language Support Overview for Programming (Chapter 16, National Language Support) and Locale Overview for Programming .

The strfmon subroutine.

[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]