strfmon() — Convert monetary value to string

Standards

Standards / Extensions C or C++ Dependencies

XPG4
XPG4.2
Single UNIX Specification, Version 3

both  

Format

#define _XOPEN_SOURCE
#include <monetary.h>

ssize_t strfmon(char * __restrict__ s, size_t maxsize, 
                const char * __restrict__ format, …);

General description

strfmon() produces a formatted monetary output string from a double argument. It has been extended to determine floating-point argument format (hexadecimal floating-point or IEEE Binary Floating-Point) using the __isBFP() function.

Note: In IEEE Binary Floating-Point mode, denormal, infinity and NaN argument values are out of range.

Places characters into the array pointed to by *s as controlled by the string pointed to by format. No more than maxsize characters are placed into the array.

The character string format contains two types of objects: plain characters, which are copied to the output array, and directives, each of which results in the fetching of zero or more arguments that are converted and formatted. The results are undefined if there are insufficient arguments for the format. If the format is exhausted while arguments remain, the excess arguments are simply ignored. If objects pointed to by s and format overlap, the behavior is undefined.

The directive (conversion specification) consists of the following sequence:
  1. A % character
  2. Optional flags: =f, ^, !, then +, C, or (
  3. Optional field width (may be preceded by w
  4. Optional left precision: #n
  5. Optional right precision: .p
  6. Required conversion character to indicate what conversion should be performed: i or n
Each directive is replaced by the appropriate characters, as described in the following list:
%i
The double argument is formatted according to the locale's international currency format (for example, in USA: USD 1,234.56). An @euro codeset modifier can be used to request "EUR" instead of a national 4-character monetary string.
%n
The double argument is formatted according to the locale's national currency format (for example, in USA: $1,234.56). An @euro codeset modifier can be used to get <euro-sign> instead of <currency>.

%% is replaced by %. No argument is converted.

The following optional conversion specifications may immediately follow the initial % of a directive:
=f
A flag, used in conjunction with the maximum digits specification #n (see below), specifies that the character f should be used as the numeric fill character. The default numeric fill character is the space character. This option does not affect the other fill operations that always use space as the fill character.
^
A flag. Do not format the currency amount with thousands grouping characters. The default is to insert the grouping characters if defined for the current locale.
Note: The code point for the ^ character will be determined according to the current LC_SYNTAX category.
+ | C | (
A flag, specifies the style of representing positive and negative currency amounts. Only one of +, C, or ( may be specified. If + is specified, the locale's equivalent of + and - are used (for example, in USA: the empty (NULL) string if positive and - if negative). If C is specified, the locale's equivalent of DB for negative and CR for positive are used. If ( is specified, the locale's equivalent of enclosing negative amounts within parentheses is used. If this option is not included, a default specified by the current locale is used.
[-]w
The field width. The decimal digit string w specifies a minimum field width in which the result of the conversion is right-justified (or left-justified if the optional flag “-” is specified).
#n
The left precision. The decimal digit string n specifies the maximum number of digits expected to be formatted to the left of the radix character. This option can be used to keep the formatted output from multiple calls to the strfmon() aligned in the same columns. It can also be used to fill unused positions with a special character as in $***123.45. This option causes an amount to be formatted as if it has the number of digits specified by n. If more digit positions are required than the number specified, conversion specification is ignored. Digit positions in excess of those actually required are filled with the numeric fill character. (See the =f specification above.)
If the thousands grouping is enabled, the behavior is:
  1. Format the number as if it is an n digit number.
  2. Insert fill characters to the left of the leftmost digit (for example, $0001234.56 or $***1234.56)
  3. Insert the separator character (for example, $0,001,234.56 or $*,**1,234.56)
  4. If the fill character is not the digit zero, the separators are replaced by the fill character (for example, $****1,234.56).

To ensure alignment, any characters appearing before or after the number in the formatted output such as currency or sign symbols are padded as necessary with space characters to make their positive and negative formats an equal length.

Note: The code point for the # character (in #n) will be determined according to the current LC_SYNTAX category.
.p
The right precision. The decimal digit string p specifies the number of digits after the radix character. If the value of the precision p is zero, no radix character appears. If this option is not included, a default specified by the current locale is used. The amount being formatted is rounded to the specified number of digits before formatting.
!
A flag used to suppress the currency symbol from the output conversion.
Note: The code point for the ! character is determined according to the current LC_SYNTAX category.

The LC_MONETARY category of the program's locale affects the behavior of this function including the monetary radix character (which is different from the numeric radix character affected by the LC_NUMERIC category), the thousands (or alternative grouping) separator, the currency symbols and formats. The international currency symbol must be in accordance with those specified in ISO4217 Codes for the representation of currencies and funds.

Formatting choices are indicated in the LC_MONETARY category for the output of both national and international monetary quantities. The national format is determined by the settings of p_cs_precedes, n_cs_precedes, p_sign_posn, n_sign_posn, p_sep_by_space, and n_sep_by_space. An equivalent set of members for international formats are added to conform with the ISO/IEC standard. See locale.h for more information on international formats.

The following tables show expected results for the various combinations of sep_by_space and sign_posn. All examples are based on a positive monetary quantity of 123.00, positive sign of '+', and currency symbol of '$'. Note that formatting rules are equivalent for negative and non-negative values as well as for national and international formats.
Table 1. Monetary formats when cs_precedes = 1
sep_by_space sign_posn
  0 1 2 3 4
0 ($123.00) +$123.00 $123.00+ +$123.00 $+123.00
1 ($ 123.00) +$ 123.00 $ 123.00+ +$ 123.00 $+ 123.00
2 ($123.00) + $123.00 $123.00 + + $123.00 $ +123.00
Table 2. Monetary formats when cs_precedes = 0
sep_by_space sign_posn
  0 1 2 3 4
0 (123.00$) +123.00$ 123.00$+ 123.00+$ 123.00$+
1 (123.00 $) +123.00 $ 123.00 $+ 123.00 +$ 123.00 $+
2 (123.00$) + 123.00$ 123.00$ + 123.00+ $ 123.00$ +
cs_precedes
0
The currency symbol follows the value.
1
The currency symbol precedes the value.
sep_by_space
0
No space separates the currency symbol and value.
1
If the currency symbol and sign string are adjacent, a space separates them from the value; otherwise, a space separates the currency symbol from the value.
2
If the currency symbol and sign string are adjacent, a space separates them; otherwise, a space separates the sign string from the value.
sign_posn
0
Parentheses surround the quantity and currency_symbol or int_curr_symbol.
1
The sign string precedes the quantity and currency_symbol or int_curr_symbol.
2
The sign string succeeds the quantity and currency_symbol or int_curr_symbol.
3
The sign string immediately precedes the currency_symbol or int_curr_symbol.
4
The sign string immediately succeeds the currency_symbol or int_curr_symbol.

Returned value

If the total number of resulting bytes including the terminating NULL character is not more than maxsize, strfmon() returns the number of bytes placed into the array pointed to by s, not including the terminating NULL character.

If unsuccessful, the contents of the array are indeterminate, strfmon() returns -1, and sets errno to one of the following values:
Error Code
Description
E2BIG
Conversion stopped due to lack of space in the buffer

Example

CELEBS41
⁄* CELEBS41 *⁄                                   
#include <localdef.h>                                                           
#include <monetary.h>                                                           
#include <stdio.h>                                                              
#include <stdlib.h>                                                             
                                                                                
int main(void)                                                                  
{                                                                               
   char   string[100];     ⁄* hold the string returned from strfmon() *⁄        
   double money = 1234.56;                                                      
                                                                                
   if (setlocale(LC_ALL, "En_US") == NULL) {                                    
      printf("Unable to setlocale().\n");                                       
      exit(1);                                                                  
   }                                                                            
                                                                                
   strfmon(string, 100, "%i", money);                                           
   printf("%s\n", string);                                                      
   strfmon(string, 100, "%n", money);                                           
   printf("%s\n", string);                                                      
}                                                                               

Example

The following example shows euro currency support:
/* EUROSAMP
   This example sets the locale to Fr_BE.IBM-1148
   and Fr_BE.IBM-1148@euro and prints a value with
   the locales national and international currency
   format.
*/

#include <localdef.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  char string[100];
  double money = 1234.56;

if (setlocale(LC_ALL,"Fr_BE.IBM-1148") == NULL) {
    printf("Unable to setlocale().\n");
    exit(1);
}

strfmon(string,100,"%i",money);
printf("%s\n",string);
strfmon(string,100,"%n",money);
printf("%s\n",string);

if (setlocale(LC_ALL,"Fr_BE.IBM-1148@euro") == NULL) {
    printf("Unable to setlocale().\n");
    exit(1);
}

strfmon(string,100,"%i",money);
printf("%s\n",string);
strfmon(string,100,"%n",money);
printf("%s\n",string);
}

Output

1.234,56 BEF
1.234,56 BF
1.234,56 EUR
1.234,56 <euro-sign>

Related information