Formatting numbers

  • Thread starter Christopher Robin
  • Start date
C

Christopher Robin

Hi,

I'm trying to find if a function exists that would format a large (> 1000)
number with comma notation on a unix type system...

I currently have
X = 10000;

printf("X = %d\n", X);
which obviously only prints:
X = 10000

I'd like it if I could find a function that would format it properly so it
would print:

X = 10,000

Any ideas... I'd rather not design/write it myself if it already exists.
 
J

Jack Klein

Hi,

I'm trying to find if a function exists that would format a large (> 1000)
number with comma notation on a unix type system...

I currently have
X = 10000;

printf("X = %d\n", X);
which obviously only prints:
X = 10000

I'd like it if I could find a function that would format it properly so it
would print:

X = 10,000

Any ideas... I'd rather not design/write it myself if it already exists.

There is no such function in the standard C library. If you do not
want to write such a function yourself, try a search on google.com for
existing source code.

Note that it doesn't really take a function, just a change in the call
to printf:

printf("X = %d,%d\n", X/1000, X%1000);

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
A

Al Bowers

Jack said:
Note that it doesn't really take a function, just a change in the call
to printf:

printf("X = %d,%d\n", X/1000, X%1000);

That would print: 10,0
ITYM printf("X = %d,%03d\n",X/1000, X%1000);
 
R

Richard Heathfield

Christopher said:
Hi,

I'm trying to find if a function exists that would format a large (> 1000)
number with comma notation on a unix type system...

If you must post the same article in more than one newsgroup, please
cross-post it to both the relevant groups in a single article, rather than
posting it separately in each group.

I have already answered your question elsenet.
 
C

CBFalconer

Al said:
That would print: 10,0
ITYM printf("X = %d,%03d\n",X/1000, X%1000);

Now try that with X = 10. 0,010

Try the following. Compile with -DTESTING=1 to check it out, omit
that to create a linkable object module.

/* --- file putnums.c ---

Using binary as an example, code to ourput numbers
in a field, while injecting commas at intervals.

By C.B. Falconer. Put in public domain.
*/
#include <stdio.h>
#include "putnums.h"

#ifdef TESTING /* Add in a demonstration driver */
# include <limits.h>

# define BASE 10 /* Try 2 through 16 here only */
# define GROUP 3 /* with 0, 4 or 3 here */
#endif

/* ------------------- */

/* The original call must pass in depth == 0 */
/* field is zero based, so 36 allows 37 chars */
static int putval(FILE *fp, unsigned long v, int base,
int field, int clump, int neg,
int depth)
{
int retval;
static char hexchars[16] = "0123456789abcdef";

if (depth && clump && ((depth % clump) == 0)) field--;
if ((v / base) > 0) {
retval = 1 + putval(fp, v/base, base, field,
clump, neg, depth+1);
}
else {
if (neg) field--;
while (field > depth) {
putc(' ', fp);
field--;
}
if (neg) {
putc('-', fp);
retval = 2;
}
else retval = 1;
}
/* Revise this for base value larger than 16 */
putc((v % base)[hexchars], fp);

if (depth && clump && ((depth % clump) == 0)) {
putc(',', fp);
retval++;
}
return retval;
} /* putval */

/* ------------------- */

/* Negative field for left justification, 0 based */
/* clump is interval for group separator, 0 for none */
int putnum(FILE *fp, long v, int base,
int field, int clump)
{
int retval;

if (v < 0) retval = putval(fp, -v, base, field, clump, 1, 0);
else retval = putval(fp, v, base, field, clump, 0, 0);
while ((field + retval) <= 0) {
field++;
putc(' ', fp);
}
return retval;
} /* putnum */

/* ------------------- */

/* Negative field for left justification, 0 based */
/* clump is interval for group separator, 0 for none */
int putunum(FILE *fp, unsigned long v, int base,
int field, int clump)
{
int retval;

retval = putval(fp, v, base, field, clump, 0, 0);
while ((field + retval) <= 0) {
field++;
putc(' ', fp);
}
return retval;
} /* putunum */

/* ------------------- */

#ifdef TESTING
int main(void)
{
int i, lgh;

for (i = 0; i < 50; i++) putchar('0' + i % 10);
putchar('\n');
for (i = 0; i < 12; i++) {
lgh = putnum(stdout, i, BASE, 36, GROUP);
putchar(' ');
lgh = putnum(stdout, lgh, BASE, 8, GROUP);
puts(".");
}
i = INT_MAX - 4;
do {
i++;
lgh = putnum(stdout, i, BASE, 36, GROUP);
putchar(' ');
lgh = putnum(stdout, lgh, BASE, 8, GROUP);
puts(".");
} while (i < INT_MAX);

i = INT_MIN + 4;
do {
i--;
lgh = putnum(stdout, i, BASE, 36, GROUP);
putchar(' ');
lgh = putnum(stdout, lgh, BASE, 8, GROUP);
puts(".");
lgh = putunum(stdout, (unsigned long)i, BASE, 36, 0);
putchar(' ');
lgh = putnum(stdout, lgh, BASE, 8, GROUP);
puts(".");
} while (i > INT_MIN);

lgh = putunum(stdout, 1, BASE, -36, GROUP);
putchar(' ');
lgh = putunum(stdout, lgh, BASE, 8, GROUP);
puts(".");

for (i = 0; i < 4; i++) {
lgh = putudnum(stdout, (unsigned long)-i, 36, GROUP);
putchar(' ');
lgh = putdnum(stdout, lgh, 8, GROUP);
puts(".");
lgh = putunum(stdout, (unsigned long)-i, 16, 36, 4);
putchar(' ');
lgh = putunum(stdout, lgh, BASE, -8, GROUP);
puts(".");
lgh = putunum(stdout, (unsigned long)-i, 2, -36, 4);
putchar(' ');
lgh = putunum(stdout, lgh, BASE, 8, GROUP);
puts(".");
}
return 0;
} /* main */
#endif
/* --- end putnums.c --- */


/* --- file putnums.h --- */
#ifndef putnums_h_
# define putnums_h_

# ifdef __cplusplus
extern "C" {
# endif

/* Using binary as an example, code to ourput numbers
in a field, while injecting commas at intervals.

By C.B. Falconer. Put in public domain.
*/

/* ------------------- */

/* Negative field for left justification, 0 based */
/* clump is interval for group separator, 0 for none */
int putnum(FILE *fp, long v, int base,
int field, int clump);

/* ------------------- */

/* Negative field for left justification, 0 based */
/* clump is interval for group separator, 0 for none */
int putunum(FILE *fp, unsigned long v, int base,
int field, int clump);

/* Macros to ease use for decimal output */
#define putdnum(fp, v, field, clump) \
putnum(fp, v, 10, field, clump)
#define putudnum(fp, v, field, clump) \
putunum(fp, v, 10, field, clump)

# ifdef __cplusplus
}
# endif
#endif
/* --- end putnums.h --- */
 
J

James Antill

Hi,

I'm trying to find if a function exists that would format a large (> 1000)
number with comma notation on a unix type system...

This should be posted to comp.unix.programer
I currently have
X = 10000;

printf("X = %d\n", X);
which obviously only prints:
X = 10000

I'd like it if I could find a function that would format it properly so it
would print:

X = 10,000

Any ideas... I'd rather not design/write it myself if it already exists.

You probably want to look at the %'d POSIX extension for printf. And to
bring it back on topic you can look at a comparison of some printf
implementations at (some of which only require plain C89)...

http://www.and.org/vstr/printf_comparison.html

....the better ones of which implement the POSIX extensions (the other
major one being the i18n parameter numbers).
 
J

Jim Showalter

Hi,

I'm trying to find if a function exists that would format a large
(> 1000) number with comma notation on a unix type system...

I currently have
X = 10000;

printf("X = %d\n", X);
which obviously only prints:
X = 10000

I'd like it if I could find a function that would format it properly
so it would print:

X = 10,000

Any ideas... I'd rather not design/write it myself if it already
exists.

Here's a function I wrote ten years ago that works for me. I made
it to support ULONG_MAX, but it could easily be extended to support
ULLONG_MAX, which <I think> would be 20 places?

/* fdigits() by JShowalter - Akron, OH Aug. 19, '93
*/

#include <stdio.h>

#define MAX_PLACES 10 /* enough places for ULONG_MAX */

char *fdigits (unsigned long integer)
{
static char fdigits[MAX_PLACES + (MAX_PLACES / 3) + 1];
char digits[MAX_PLACES + 1];
char *dgt = digits, *fdgt = fdigits;
int places;

places = sprintf(digits, "%lu", integer); /* convert integer to string */
/* places = digits in string */
while (*fdgt++ = *dgt++) /* while there are more digits*/
if (--places) /* if places-1 > 0 */
if ( !(places % 3) ) /* if places is multiple of 3 */
*fdgt++ = ','; /* insert a comma here */
return fdigits;
}

int main (void)
{
printf("num=%s\n", fdigits(1234567890));
return 0;
}


HTH,
jim

_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/
_/ Question:
_/ What's the difference between car salesmen and computer
_/ salesmen?
_/ Answer:
_/ Car salesmen _know_ when they're lying.
_/
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,083
Messages
2,570,591
Members
47,212
Latest member
RobynWiley

Latest Threads

Top