rouben@math16.math.umbc.edu (Rouben Rostamian) (06/24/91)
I need help with printing numbers (floating or integer) in C. I would like to display the numbers in three-digit comma-separated format. For instance, the integer 12345678 should be printed as 12,345,678. The floating point number 1234.56789 may be printed as 1,234.5678 or as 1,234.567,8. I wish the printf function had an option for such formatting, but as far as I know, it doesn't. I guess the ideal solution would be to extend the format options for the printf command. Perhaps a Printf function may be defined which accepts the standard formatting strings of the printf function, but which also accepts additional conversion characters to print comma-separated digits. I do not wish to re-invent the wheel if someone has already done this. So please let me know if there is something similar available somewhere. -- Rouben Rostamian Telephone: (301) 455-2458 Department of Mathematics and Statistics e-mail: University of Maryland Baltimore County bitnet: rostamian@umbc.bitnet Baltimore, MD 21228, U.S.A. internet: rouben@math9.math.umbc.edu
angst@fig.ucsb.edu (Hopelessly in love w/Donna Reed) (06/24/91)
[This should have been posted to comp.lang.c; I have directed followups there.] In article <1991Jun23.174550.14820@umbc3.umbc.edu> rouben@math16.math.umbc.edu (Rouben Rostamian) writes: > >I need help with printing numbers (floating or integer) in C. I would like >to display the numbers in three-digit comma-separated format. For instance, >the integer 12345678 should be printed as 12,345,678. The floating point >number 1234.56789 may be printed as 1,234.5678 or as 1,234.567,8. >I wish the printf function had an option for such formatting, but >as far as I know, it doesn't. This function will work. It assumes the number is contained in a string (which you can do by using sprintf()) -- void commas (char *s) { char *p = index (s, '.'); int count; if (p) *p = '\0'; /* ignore fractional part for now */ count = strlen (s); while (count-- > 0) { putchar (*s++); if (count > 0 && count % 3 == 0) putchar (','); } if (p) printf (".%s", p+1); /* print out fractional part */ } Here's the output of the short program I wrote to test this: Script started on Sun Jun 23 16:37:37 1991 manray% a.out enter string: 123 123 enter string: 1234 1,234 enter string: 123456 123,456 enter string: 12345678901 12,345,678,901 enter string: 34.2732 34.2732 enter string: 35276.28321 35,276.28321 enter string: ^C manray% exit script done on Sun Jun 23 16:38:03 1991 "Let the fools have their tartar sauce." | Dave Stein - Mr. Burns | angst@cs.ucsb.edu | angst%cs@ucsbuxa.bitnet
art@pilikia.pegasus.com (Arthur Neilson) (06/25/91)
In article <1991Jun23.174550.14820@umbc3.umbc.edu> rouben@math16.math.umbc.edu (Rouben Rostamian) writes: > >I need help with printing numbers (floating or integer) in C. I would like >to display the numbers in three-digit comma-separated format. For instance, >the integer 12345678 should be printed as 12,345,678. The floating point >number 1234.56789 may be printed as 1,234.5678 or as 1,234.567,8. I use the function below quite a bit, it formats doubles in a char buffer according to a picture clause type specification. I didn't write it, I got it off the net a long time ago and forget where it came from. -----8<----- cut here -----8<----- cut here -----8<----- cut here -----8<----- /* * f o r m a t * * Format double value as char string in buffer based * on the picture format passed in the format string. * * Recognised format characters: * * * Digit or asterisk prefix * $ Digit or dollar-sign prefix * - Digit or minus-sign prefix if negative * + Digit or sign prefix * ( Digit or left-parenthesis prefix if negative * # Digit or blank prefix * & Digit or zero prefix * ) Right-parenthesis suffix if negative * . Decimal point * , Comma or space prefix * < Digit or space appended after format (left justification) * * This function uses only fabs(), fmod(), and floor(), * it should be compatible with any system that has a * standard C math library. */ #include <math.h> char * format(buf, fmt, val) char *buf; char *fmt; double val; { double decval; int didlead, didsign, pad, signum, overflow; register char *fmtp, *bufp, *decp; char tbuf[1024]; char *retp = buf; signum = (val < 0.0); val = fabs(val); for (decp = fmt; *decp; decp++) if (*decp == '.') break; /* * Make a first pass to calculate a rounding value. */ decval = 0.5; for (fmtp = decp; *fmtp; fmtp++) { switch (*fmtp) { case '*': case '$': case '-': case '+': case '(': case '#': case '&': case '<': decval /= 10.0; break; } } val += decval; fmtp = decp; decval = val - floor(val); val = floor(val); pad = 0; didlead = 0; didsign = 0; bufp = tbuf; while (fmtp != fmt) { switch (*--fmtp) { case '#': case '<': if (val < 1.0) { if (*fmtp == '<') pad++; else *bufp++ = ' '; break; } /* FALLTHROUGH */ case '&': *bufp++ = (int) fmod(val, 10.0) + '0'; val /= 10.0; break; case '*': if (val >= 1.0) { *bufp++ = (int) fmod(val, 10.0) + '0'; val /= 10.0; break; } *bufp++ = (didlead ? ' ' : '*'); didlead = 1; break; case '$': if (val >= 1.0) { *bufp++ = (int) fmod(val, 10.0) + '0'; val /= 10.0; break; } *bufp++ = (didlead ? ' ' : '$'); didlead = 1; break; case '-': if (val >= 1.0) { *bufp++ = (int) fmod(val, 10.0) + '0'; val /= 10.0; break; } *bufp++ = (didsign ? ' ' : (signum ? '-' : ' ')); didsign = 1; break; case '+': if (val >= 1.0) { *bufp++ = (int) fmod(val, 10.0) + '0'; val /= 10.0; break; } *bufp++ = (didsign ? ' ' : (signum ? '-' : '+')); didsign = 1; break; case '(': if (val >= 1.0) { *bufp++ = (int) fmod(val, 10.0) + '0'; val /= 10.0; break; } *bufp++ = (didsign ? ' ' : (signum ? '(' : ' ')); didsign = 1; break; case ')': *bufp++ = (signum ? ')' : ' '); break; case ',': *bufp++ = (val < 1.0 ? ' ' : ','); break; default: *bufp++ = *fmtp; } } overflow = (val >= 1.0); while (bufp-- != tbuf) *buf++ = (overflow ? '*' : *bufp); /* * Decimals turn out to be easy, since we can parse forward and all * the potential digit chars can be treated as "&". Also, extracting * digits is done via (decval *= 10.0; floor(decval)) instead of slow * fmod(). */ while (*decp) { if (overflow) *buf++ = '*'; else { switch (*decp) { case '*': case '$': case '-': case '+': case '(': case '#': case '&': case '<': decval *= 10.0; *buf++ = (int) floor(decval) + '0'; decval -= floor(decval); break; case ')': *buf++ = (signum ? ')' : ' '); break; default: *buf++ = *decp; break; } } decp++; } while (pad--) *buf++ = (overflow ? '*' : ' '); *buf = '\0'; return (retp); } -----8<----- cut here -----8<----- cut here -----8<----- cut here -----8<----- -- Arthur W. Neilson III | INET: art@pilikia.pegasus.com Bank of Hawaii Tech Support | UUCP: uunet!ucsd!nosc!pilikia!art