home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
xbase
/
library
/
clipper
/
rettig
/
source
/
tomoney.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-21
|
6KB
|
181 lines
/*********
* Function: TOMONEY
* By: Tom Rettig
*
* Placed in the public domain by Tom Rettig Associates, 10/22/1990.
*
* Syntax: TOMONEY( <expN> )
* Return: <expC> "... dollars, and ... cents"
* Null string if passed invalid parameter.
* Asterisks if passed too large a number.
* Note..: Rounds to two decimal places.
* Return string length varies in size.
********/
#include "trlib.h"
TRTYPE tomoney()
{
static char *units[] =
{ "NO",
"ONE", "TWO", "THREE", "FOUR", "FIVE",
"SIX", "SEVEN", "EIGHT", "NINE", "TEN",
"ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN",
"SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
};
static char *teens[] =
{ " ", /*space*/
"TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY",
"SIXTY", "SEVENTY", "EIGHTY", "NINETY", " HUNDRED"
};
static char *magnitude[] =
{ "", /*unused null*/
" THOUSAND", " MILLION", " BILLION",
" TRILLION", " QUADRILLION", " QUINTILLION"
};
static char *misc[] =
{ " and ",
HYPHEN, ", ", " DOLLAR", " DOLLARS", " CENT", " CENTS"
};
static char funcname[] = { "tomoney" };
char *aptr[PTRMAX]; /* array of pointers to word strings */
int i, magi; /* indexes into aptr[i] and magnitude[magi] arrays */
char *instr, *pos, *hold; /* input pointers */
char *ret, *iret, *p; /* output pointers */
int allzero, zeroflag, iszero; /* flags for zero values */
double temp;
if ( PCOUNT == 1 && ISNUM(1) )
{
/* allocate memory for input and output buffers */
instr = _tr_allocmem( (unsigned) (INPUTMAX+1));
if ( !instr )
{
_retc( _tr_errmsgs(funcname,E_ALLOC) );
return;
}
ret = _tr_allocmem( (unsigned) (OUTPUTMAX+1));
if ( !ret )
{
_tr_freemem( instr,(unsigned)INPUTMAX+1);
_retc( _tr_errmsgs(funcname,E_ALLOC) );
return;
}
hold = instr;
/* internal "numeric to ascii": */
/* _tr_ntoa( (double)param, (int)len, (int)decimals, (char *)output ) */
temp = _parnd(1);
temp = _tr_fabs(temp);
_tr_ntoa( temp, INPUTMAX, DECIMAX, instr );
if ( *instr == '*' )
{
_retc( NUM_OVRFLW ); /* return asterisks if overflow */
_tr_freemem( hold,(unsigned)INPUTMAX+1); /* free instr */
_tr_freemem( ret,(unsigned)OUTPUTMAX+1);
return;
}
/* point to first digit, and find decimal point */
while ( *instr == SPACEC)
instr++;
pos = instr;
while ( *pos!=DECPOINT && *pos )
pos++;
/* set pointers to each word, going from least significant digit to most */
i = 0;
if ( pos[2] == '1' && pos[1] == ZEROC ) /* one cent */
aptr[i++] = misc[5]; /* " CENT" */
else
aptr[i++] = misc[6]; /* " CENTS" */
/* cents digits */
if ( pos[2] == ZEROC && pos[1] == ZEROC ) /* zero cents */
aptr[i++] = units[0]; /* "NO" */
else
aptr[i++] = pos+1; /* cents string of digits */
/* separate dollars from cents */
aptr[i++] = misc[0]; /* " and " */
if ( pos[-1] == '1' && pos == instr+1 ) /* one dollar */
aptr[i++] = misc[3]; /* " DOLLAR" */
else
aptr[i++] = misc[4]; /* " DOLLARS" */
if ( pos[-1] == ZEROC && pos == instr+1 ) /* zero dollars */
aptr[i++] = units[0]; /* "NO" */
else
{
allzero = TRUE; /* scope of all magnitudes */
zeroflag = TRUE; /* scope of previous and current magnitudes */
iszero = TRUE; /* scope of current magnitude only */
/* loop through each magnitude of three digits until done */
for ( magi=0; pos>instr; pos+=(-3), magi++ )
{
/* zero flag settings */
if ( zeroflag && !iszero )
zeroflag = allzero = FALSE;
iszero = ( pos[-1]==ZEROC && pos[-2]==ZEROC && pos[-3]==ZEROC );
if ( !zeroflag && iszero )
zeroflag = TRUE;
/* magnitude */
if ( magi && !iszero )
{
if ( !zeroflag || !allzero )
aptr[i++] = misc[2]; /* magnitude delimiter */
aptr[i++] = magnitude[magi];
}
/* units and teens values */
if ( pos[-1] > ZEROC )
{
if ( (pos[-2] == ZEROC || pos < instr+2) )
aptr[i++] = units[ ONES(pos) ];
else if ( pos[-2] == '1' )
aptr[i++] = units[ (TENS(pos)*10) + ONES(pos) ];
else if ( pos[-2] > '1' && pos >= instr+2 )
{
aptr[i++] = units[ ONES(pos) ];
aptr[i++] = misc[1]; /* HYPHEN */
aptr[i++] = teens[ TENS(pos) ];
}
}
else if ( pos[-2] > ZEROC && pos >= instr+2 )
aptr[i++] = teens[ TENS(pos) ];
/* hundreds value */
if ( pos[-3] > ZEROC && pos >= instr+2 )
{
if ( pos[-2] > ZEROC || pos[-1] > ZEROC )
aptr[i++] = teens[0]; /* " " */
aptr[i++] = teens[10]; /* " HUNDRED" */
aptr[i++] = units[ HUNS(pos) ];
}
} /* endwhile */
} /* endif */
/* concatenate word pointers into one string and store in output buffer */
iret = ret;
i--;
while ( i >= 0 )
{
p = aptr[i--];
while ( *p )
*iret++ = *p++;
}
*iret = NULLC;
_retc( ret );
_tr_freemem( hold,(unsigned)INPUTMAX+1 ); /*free instr*/
_tr_freemem( ret,(unsigned)OUTPUTMAX+1 );
}
else
_retc( _tr_errmsgs(funcname,E_SYNTAX) );
}
/* eof */