mnyfmt.c: Format money or currency amounts
Macros | Typedefs | Functions
mnyfmt.h File Reference

Header file for mnyfmt(). More...

Go to the source code of this file.

Macros

#define mnyfmt_size   96
 (2^128 < 10^40) && (2*40 < 96) ==> char[96] is big enough for 128 bits More...
 
#define mnyfmt_format_char   (char)('9')
 Formatting character for mnyfmt(). More...
 

Typedefs

typedef long long mnyfmt_long
 

Functions

char * mnyfmt (char *fmtstr, char dec, mnyfmt_long moneyval, unsigned CE)
 Formats and stores in fmtstr the money amount. More...
 
mnyfmt_long str2mnyCE (const char *amount, char dec, unsigned CE)
 Returns an integer value that corresponds to 'amount', scaled 10^CE digits. More...
 
char * mnyfmt0 (char *fmtstr, mnyfmt_long moneyval)
 return mnyfmt(fmtstr, '\0', moneyval, 0 ) More...
 

Detailed Description

Header file for mnyfmt().

This C function formats money amounts using a picture clause.

See also
http://google.com/search?as_qdr=all&num=100&as_q=picture+clause
Author
Adolfo Di Mare adolf.nosp@m.o@di.nosp@m.-mare.nosp@m..com
Date
2013

Definition in file mnyfmt.h.

Macro Definition Documentation

#define mnyfmt_size   96

(2^128 < 10^40) && (2*40 < 96) ==> char[96] is big enough for 128 bits

Definition at line 23 of file mnyfmt.h.

#define mnyfmt_format_char   (char)('9')

Formatting character for mnyfmt().

Definition at line 26 of file mnyfmt.h.

Typedef Documentation

typedef long long mnyfmt_long

Definition at line 17 of file mnyfmt.h.

Function Documentation

char* mnyfmt ( char *  fmtstr,
char  dec,
mnyfmt_long  moneyval,
unsigned  CE 
)

Formats and stores in fmtstr the money amount.

Before invocation, the formatting pattern (picture clause) is stored in result string fmtstr. To avoid using (double) values that have many round off problems, the parameter for this function is an integer scaled to 10^CE digits. For example, when using CE==2 digits, the monetary value "$2,455.87" is representad by the integer '245587', and if CE==4 digits are used, the integer value would be '24558700'.

  • The (integer) value to format is moneyval.
  • Overwrites fmtstr with the formatted value.
  • On error, leaves fmtstr untouched and returns (char*)(0).
  • If the fmtstr does not have enough format characters '9' for the integer part to format, of if the '-' cannot fit on top of a '9' character, fmtstr remains untouched and the value returned is (char*)(0).
  • The valid range for CE, the 'currenct exponent', is [0..6] [ a CE of 7 or bigger leaves fmtstr untouched and the value returned is (char*)(0) ].
  • The first occurrence of the character dec is the decimal fraction separator (usually '.' or ',').
  • When the decimal fraction separator character dec does not appear in fmtstr it is assumed to be '\0' (end of string character).
  • After the dec separator all the leading consecutive '9' format characters are substituted with the corresponding digit from the decimal part in moneyval, using digit zero '0' as fill character.
  • All digits that inmediatly follow the decimal fraction separator are changed either to zero or to the corresponding digit taken from the decimal part in moneyval.
  • Both the integer part and the fractional part are filled with the digits that correspond to its position. This means that a format string like "9999.9999" wild yield "0123.8700" as result when moneyval==1238700 and CE==4.
  • Characters trailing after the dec separator that are not the '9' format digit are left untouched.
  • All format characters '9' appearing before the decimal separator dec will be replaced by digit zero '0' if the corresponding digit in moneyval is not significant.
  • When moneyval is negative, the '-' sign will be place over the '9' immediately before the more significant digit.
  • Non format characters in fmtstr are left untouched.
  • The negative sign always is '-' and it is always placed on top of the corresponding format character.
  • Returns (char*)(0) when the formatted value does not fit within strlen(fmtstr) characters.
  • Returns a pointer to the first significant digit in the formatted string, within fmtstr or to the '-' sign if the formatted value is negative.
  • Before storing the format string in fmtstr, the programmer must ensure that fmtstr is big enough to hold the format string.
Remarks
  • This routine basically substitutes each '9' character in fmtstr for its corresponding decimal digit, or '0' when it is not a significant digit. All other characters within fmtstr remain untouched.
  • As it happens with many C functions, before invocation the programmer must be sure that fmtstr is big enough to copy on it the complete format string, as otherwise memory beyond fmtstr would be overwritten.
  • There is no (wchart_t) version for this function, as it is meant to place digits in a formatting string. After placement, the result string can be converted to other forms.
1 {{ // test.example
1  // (2^128 < 10^40) && (2*40<96) ==> char[96] holds a
2  char *sgn, fmtstr[96],mem[96]; // 128 bit integer
3 
4  unsigned CE, ten_pow_CE;
5  CE = 2; ten_pow_CE = 100; // 10^CE -> "Currency Exponent"
6 
7  strcpy( mem, "USD$ " ); // Picture clause
8  strcpy( fmtstr , "99,999,999.99999" );
9  if (( sgn = mnyfmt( fmtstr , '.' ,-10245587,CE ) )) {
10  assertTrue( eqstr( fmtstr , "0-,102,455.87000") );
11  if ( (*sgn=='-') && (','==*(sgn+1)) ) { ++sgn; *sgn='-'; }
12  assertTrue( eqstr( sgn, "-102,455.87000") );
13 
14  strcat( mem , sgn );
15  assertTrue( eqstr( mem, "USD$ -102,455.87000") );
16  }
17  else {
18  assertFalse( "ERROR [???]: " "-102,455.87000" );
19  }
20 }}

See also
mnyfmtts.c

Definition at line 102 of file mnyfmt.c.

mnyfmt_long str2mnyCE ( const char *  amount,
char  dec,
unsigned  CE 
)

Returns an integer value that corresponds to 'amount', scaled 10^CE digits.

  • For " -102,455.87" returns '-102_455_8700' when CE==4 && dec=='.'.
  • For " -102,455.07" returns '-102_455_07' when CE==2 && dec=='.'.
  • For " -102,455.87" returns '-102_455' when CE==0 && dec=='.'.
  • The decimal separator is 'dec'.
  • CE is the 'currency exponent'.
  • Requires 'CE<=6' <–> scale up to 10^6 <–> 6 decimal digits.
1 {{ // test::str2mnyCE()
1  assertTrue( -1024550700 == str2mnyCE(" -102,455.07", '.', 4) );
2  assertTrue( -102455070 == str2mnyCE(" -102,455.07", '.', 3) );
3  assertTrue( -10245507 == str2mnyCE(" -102,455.07", '.', 2) );
4  assertTrue( -1024550 == str2mnyCE(" -102,455.07", '.', 1) );
5  assertTrue( -102455 == str2mnyCE(" -102,455.07", '.', 0) );
6 
7  assertTrue( 1024558700 == str2mnyCE(" 102,455.87", '.', 4) );
8  assertTrue( 102455870 == str2mnyCE(" 102,455.87", '.', 3) );
9  assertTrue( 10245587 == str2mnyCE(" 102,455.87", '.', 2) );
10  assertTrue( 1024558 == str2mnyCE(" 102,455.87", '.', 1) );
11  assertTrue( 102455 == str2mnyCE(" 102,455.87", '.', 0) );
12 }}

See also
str2mnyCE.c

Definition at line 40 of file str2mnyCE.c.

mnyfmt0 ( char *  fmtstr,
mnyfmt_long  moneyval 
)
inline

return mnyfmt(fmtstr, '\0', moneyval, 0 )

Definition at line 79 of file mnyfmt.h.