whatluo wrote:
I'm now working on a program which will convert dec number to
hex and oct and bin respectively, I've checked the clc but with no
luck, so can anybody give me a hit how to make this done without
strtol or s/printf function.
I just happen to have this lying about
:
/* base2txt.h. Public domain by C.B. Falconer, 2005-05-12. */
/* Output values to a text stream. No buffers needed */
#ifndef H_base2txt_h
# define H_base2txt_h
# ifdef __cplusplus
extern "C"
{
# endif
#include <stdio.h>
/* ----------------------- */
/* Convert unsigned value to stream of digits in base base.
A NULL value for f returns a char count with no output
Returns count of chars. output
return is negative for any output error */
int unum2txt(unsigned long n, unsigned int base, FILE *f);
/* ----------------------- */
/* Convert signed value to stream of digits in base base.
A NULL value for f returns a char count with no output
Returns count of chars. output
return is negative for any output error */
int num2txt(long n, unsigned int base, FILE *f);
/* ----------------------- */
/* Convert unsigned value to stream of decimal digits in fld.
A NULL value for f returns a char count with no output
A negative fld left justifies, else right.
Returns count of chars. output
return is negative for any output error */
int unum2fld(unsigned long n, int fld, FILE *f);
/* ----------------------- */
/* Convert signed value to stream of decimal digits in fld.
A NULL value for f returns a char count with no output
A negative fld left justifies, else right.
Returns count of chars. output
return is negative for any output error */
int num2fld(long n, int fld, FILE *f);
# ifdef __cplusplus
}
# endif
#endif
/* base2txt.c. Public domain by C.B. Falconer, 2005-05-12. */
/* <http://cbfalconer.home.att.net> */
/* Output values to a text stream. No buffers needed */
/* To compile a test version use -DTESTING with gcc */
/* To avoid recursion use -DNORECURSE with gcc. This */
/* may be useful on some non-conforming systems. */
#include "base2txt.h"
/* ----------------------- */
/* Convert unsigned value to stream of digits in base
A NULL value for f returns a char count with no output
Returns count of chars. output
return is negative for any output error */
int unum2txt(unsigned long n, unsigned int base, FILE *f)
{
/* MUST be a power of 2 in length */
static char hexchars[] = "0123456789abcdef";
/* allow for terminal '\0' */
#define MAXBASE (sizeof(hexchars)-1)
#ifdef NORECURSE
#include <limits.h>
int count, ix;
/* sufficient for a binary expansion */
char buf[CHAR_BIT * sizeof(long)];
#else
int count, err;
#endif
if ((base < 2) || (base > MAXBASE)) base = 10;
#ifdef NORECURSE
count = ix = 0;
do {
buf[ix++] = hexchars[(n % base) & (MAXBASE-1)];
} while ((n = n / base));
while (ix--) {
count++;
if (f && (putc(buf[ix], f) < 0)) return -count;
}
#else
count = 1;
if (n / base) {
if ((err = unum2txt(n / base, base, f)) < 0) return err;
else count += err;
}
if (f && (putc(hexchars[(n % base) & (MAXBASE-1)], f) < 0))
return -count;
#endif
return count;
} /* unum2txt */
/* ----------------------- */
/* Convert signed value to stream of digits in base
A NULL value for f returns a char count with no output
Returns count of chars. output
return is negative for any output error */
int num2txt(long n, unsigned int base, FILE *f)
{
int count, err;
unsigned long val;
val = n; count = 0;
if (n < 0) {
count++; val = -(unsigned long)n;
if (f && (putc('-', f) < 0)) return - count;
}
err = unum2txt(val, base, f);
if (err < 0) return err - count;
return err + count;
} /* num2txt */
/* ----------------------- */
/* Negative return if i/o error occurs */
/* Returns number of blanks output attempted */
static int putblks(int count, FILE *f)
{
int ix;
if (f && (count > 0)) {
for (ix = 0; ix < count; ix++) {
if (putc(' ', f) < 0) return -ix - 1;
}
return ix;
}
else return 0;
} /* putblks */
/* ----------------------- */
/* Convert unsigned value to stream of decimal digits in fld.
A NULL value for f returns a char count with no output
A negative fld left justifies, else right.
Returns count of chars. output
return is negative for any output error */
int unum2fld(unsigned long n, int fld, FILE *f)
{
int err, digs, blanks;
if (fld >= 0) { /* right justify in field */
digs = unum2txt(n, 10, NULL);
if (0 > (blanks = putblks(fld - digs, f))) return blanks;
if (0 > (err = unum2txt(n, 10, f))) return err - blanks;
else return err + blanks;
}
else { /* left justify */
if ((digs = unum2txt(n, 10, f)) < 0) return digs;
if (0 > (blanks = putblks(fld - digs, f)))
return blanks - digs;
else return blanks + digs;
}
} /* unum2fld */
/* ----------------------- */
/* Convert signed value to stream of decimal digits in fld.
A NULL value for f returns a char count with no output
A negative fld left justifies, else right.
Returns count of chars. output
return is negative for any output error */
int num2fld(long n, int fld, FILE *f)
{
int err, digs, blanks;
if (fld >= 0) { /* right justify in field */
digs = num2txt(n, 10, NULL);
if (0 > (blanks = putblks(fld - digs, f))) return blanks;
if (0 > (err = num2txt(n, 10, f))) return err - blanks;
else return err + blanks;
}
else { /* left justify */
if ((digs = num2txt(n, 10, f)) < 0) return digs;
if (0 > (blanks = putblks(fld - digs, f)))
return blanks - digs;
else return blanks + digs;
}
} /* num2fld */
#ifdef TESTING
/* ----------------------- */
/* This does some questionable things in order to get values to
display. This doesn't affect the validity of the routines */
int main(int argc, char **argv)
{
unsigned int base;
long num;
int fieldused;
if ((argc < 3) || (1 != sscanf(argv[1], "%u", &base)))
puts("Usage: base2txt base value [value ...]\n"
" where the value list is in decimal");
else {
printf("Dec.Input Base %u value [digs]\n", base);
while (argc > 2) {
sscanf(argv[--argc], "%ld", &num);
printf("%11s .", argv[argc]);
fieldused = unum2txt(num, base, stdout);
if (fieldused != unum2txt(num, base, NULL))
fputs("*ERROR*", stdout);
printf(". [%d] .", fieldused);
fieldused = num2txt(num, base, stdout);
if (fieldused != num2txt(num, base, NULL))
fputs("*ERROR*", stdout);
printf(". [%d]\n", fieldused);
}
}
return 0;
} /* main, testing */
#endif
--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson