mnyfmt.c: Format money or currency amounts
mnyfmt.h
Go to the documentation of this file.
1 // mnyfmt.h (C) 2013 adolfo@di-mare.com
2 // mnyfmt.c: A simple function to format money or currency amounts
3 
4 /** \file mnyfmt.h
5  \brief Header file for \c mnyfmt().
6  This C function formats money amounts using a picture clause.
7  \see http://google.com/search?as_qdr=all&num=100&as_q=picture+clause
8 
9  \author Adolfo Di Mare <adolfo@di-mare.com>
10  \date 2013
11 */
12 
13 #ifndef MNYFMT_ADOLFO
14 #define MNYFMT_ADOLFO
15 
16 #ifndef MNYFMT_NO_LONG_LONG
17  typedef long long mnyfmt_long;
18 #else
19  typedef long mnyfmt_long;
20 #endif
21 
22 /// (2^128 < 10^40) && (2*40 < 96) ==> char[96] is big enough for 128 bits
23 #define mnyfmt_size 96
24 
25 /// Formatting character for \c mnyfmt().
26 #define mnyfmt_format_char (char)('9')
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 // CE->Currency Exponent ==> MCE->Minor Currency Unit
33 
34 // The complete Doxygen documentation is in file 'mnyfmt.c'
35 // Examples and unit test cases are in in file 'mnyfmtts.c'
36 
37 /* Formats 'moneyval' leaving the result in picture clause 'fmtstr'.
38  The money amount stored in 'moneyval' is an integer scaled to 'CE' digits
39  and the decimal separator is 'dec'.
40 
41  For example, when using CE==2 digits, the monetary value $-455.87 should
42  be stored in variable 'moneyval' as the integer '-45587', and if CE==4
43  digits are used, 'moneyval' should be '-4558700'.
44 
45  The format string has many '9's that get replaced by the corresponding
46  digit. For example, when "999,999,999.99" is stored in 'fmtstr', the
47  computed result for '-455.87' would be "0,00-,455.87" and the pointer
48  value returned would point to '-' within 'fmtstr' (for this example,
49  CE==2 and dec=='.').
50 */
51 char* mnyfmt(char *fmtstr, char dec, mnyfmt_long moneyval, unsigned CE);
52 
53 /* // test.neg.comma
54  // (2^128 < 10^40) && (2*40<96) ==> char[96] holds a 128
55  char *sgn, fmtstr[96]; // bit integer
56 
57  strcpy( fmtstr , "9,999,999.99" );
58  if (( sgn = mnyfmt( fmtstr , '.' ,-45587,2 ) )) {
59  assertTrue( eqstr( sgn, "-,455.87" ) );
60  assertTrue( eqstr( fmtstr, "0,00-,455.87" ) );
61  // handle the "-," problem
62  if ( (*sgn=='-') && (','==*(sgn+1)) ) {
63  ++sgn; *sgn = '-'; // put '-' sign in a nice place
64  }
65  assertTrue( eqstr( sgn, "-455.87" ) );
66  assertTrue( eqstr( fmtstr, "0,00--455.87" ) );
67  }
68 */
69 
70 // Use this function to build a money amount from a string
71 mnyfmt_long str2mnyCE( const char * amount , char dec , unsigned CE );
72 
73 #ifdef __cplusplus
74 }
75 #endif
76 
77 #ifdef __cplusplus
78  // shortcut for integer only formatting
79  inline char* mnyfmt0(char *fmtstr, mnyfmt_long moneyval ) {
80  return mnyfmt(fmtstr, '\0', moneyval, 0 );
81  }
82 #else
83  #if 0
84  // Does C have the "inline" optimization?
85  static char* mnyfmt0(char *fmtstr, mnyfmt_long moneyval ) {
86  return mnyfmt(fmtstr, '\0', moneyval, 0 ) {
87  }
88  #else
89  // Use a macro to inline the invocation.
90  #define mnyfmt0(fmtstr,moneyval) mnyfmt(fmtstr, '\0', moneyval, 0 )
91  #endif
92 #endif
93 
94 /// \fn mnyfmt0(char*,mnyfmt_long)
95 /// \brief <code>return mnyfmt(fmtstr, '\0', moneyval, 0 )</code>
96 
97 #endif
98 // EOF: mnyfmt.h
char * mnyfmt0(char *fmtstr, mnyfmt_long moneyval)
return mnyfmt(fmtstr, '\0', moneyval, 0 )
Definition: mnyfmt.h:79
long long mnyfmt_long
Definition: mnyfmt.h:17
char * mnyfmt(char *fmtstr, char dec, mnyfmt_long moneyval, unsigned CE)
Formats and stores in fmtstr the money amount.
Definition: mnyfmt.c:102
mnyfmt_long str2mnyCE(const char *amount, char dec, unsigned CE)
Returns an integer value that corresponds to 'amount', scaled 10^CE digits.
Definition: str2mnyCE.c:40