bowsayge wrote:

Rich Grise said to us:

.... snip ...

It's also an awful lot of rigamarole - why not just allocate

temp[] to write the bit digits to, then do

data[pos++] = temp[pos2--]. You could also stack them.

Yes! That'll eliminate the need to reverse the string. Thanks.

Nothing wrong with reversing strings. A routine to do so is short

and quite efficient, and useful elsewhere. Now that you have

beaten this to death take a look at the following (which I have

published before). Only the first 80 odd lines are generically

useful, the rest is stuff to exercise it and convince oneself that

it works correctly.

/* Routines to display values in various bases */

/* with some useful helper routines. */

/* by C.B. Falconer, 19 Sept. 2001 */

/* Released to public domain. Attribution appreciated */

#include <stdio.h>

#include <string.h>

#include <limits.h> /* ULONG_MAX etc. */

/* ======================= */

/* reverse string in place */

size_t revstring(char *stg)

{

char *last, temp;

size_t lgh;

lgh = strlen(stg);

if (lgh > 1) {

last = stg + lgh; /* points to '\0' */

while (last-- > stg) {

temp = *stg; *stg++ = *last; *last = temp;

}

}

return lgh;

} /* revstring */

/* ============================================ */

/* Mask and convert digit to hex representation */

/* Output range is 0..9 and a..f only */

int hexify(unsigned int value)

{

static char hexchars[] = "0123456789abcdef";

return (hexchars[value & 0xf]);

} /* hexify */

/* ================================================== */

/* convert unsigned number to string in various bases */

/* 2 <= base <= 16, controlled by hexify() */

/* Returns actual output string length */

size_t basedisplay(unsigned long number, unsigned int base,

char *stg, size_t maxlgh)

{

char *s;

/* assert (stg[maxlgh]) is valid storage */

s = stg;

if (maxlgh && base)

do {

*s = hexify(number % base);

s++;

} while (--maxlgh && (number = number / base) );

*s = '\0';

revstring(stg);

return (s - stg);

} /* basedisplay */

/* ================================================ */

/* convert signed number to string in various bases */

/* 2 <= base <= 16, controlled by hexify() */

/* Returns actual output string length */

size_t signbasedisplay(long number, unsigned int base,

char * stg, size_t maxlgh)

{

char *s;

size_t lgh;

unsigned long n;

s = stg; lgh = 0;

n = (unsigned long)number;

if (maxlgh && (number < 0L)) {

*s++ = '-';

maxlgh--;

n = -(unsigned long)number;

lgh = 1;

}

lgh = lgh + basedisplay(n, base, s, maxlgh);

return lgh;

} /* signbaseddisplay */

/* ==================== */

/* flush to end-of-line */

int flushln(FILE *f)

{

int ch;

while ('\n' != (ch = fgetc(f)) && (EOF != ch)) /* more */;

return ch;

} /* flushln */

/* ========== END of generically useful routines ============ */

/* ========================= */

/* Prompt and await <return> */

static void nexttest(char *prompt)

{

static char empty[] = "";

if (NULL == prompt) prompt = empty;

printf("\nHit return for next test: %s", prompt);

fflush(stdout);

flushln(stdin);

} /* nexttest */

/* ============================== */

/* Display a value and its length */

static void show(char *caption, int sz, char *stg)

{

if ((unsigned)sz != strlen(stg))

printf("Something is wrong with the sz value\n");

printf("%s: sz = %2d \"%s\"\n", caption, sz, stg);

} /* show */

/* =========== */

/* exercise it */

int main(void)

{

#define LGH 40

#define VALUE 1234567890

char stg[LGH];

unsigned int base;

int sz;

printf("\nExercising basedisplay routine\n");

printf("\nbase sz value\n");

for (base = 2; base <= 16; base++) {

sz = (int)basedisplay(VALUE, base, stg, LGH - 1);

printf("%2d %2d %s\n", base, sz, stg);

}

nexttest("ULONG_MAX");

for (base = 8; base <= 16; base++) {

sz = (int)basedisplay(ULONG_MAX, base, stg, LGH - 1);

printf("%2d %2d %s\n", base, sz, stg);

}

basedisplay(0, 10, stg, 3);

printf("\nzero %s\n", stg);

basedisplay(VALUE, 10, stg, 3);

printf("3 lsdigits only, base 10 %s\n", stg);

printf("\nBad calls:\n");

sz = (int)basedisplay(VALUE, 10, stg, 0);

show("0 length field", sz, stg);

sz = (int)basedisplay(VALUE, 1, stg, 20);

show("base 1, lgh 20", sz, stg);

sz = (int)basedisplay(VALUE, 0, stg, 20);

show("base 0, lgh 20", sz, stg);

sz = (int)signbasedisplay(-1234, 10, stg, 0);

show("0 lgh fld, -ve", sz, stg);

sz = (int)signbasedisplay(-1234, 10, stg, 2);

show("truncate -1234", sz, stg);

nexttest("System limits");

sz = (int)signbasedisplay(SCHAR_MIN, 10, stg, 20);

show("SCHAR_MIN ", sz, stg);

sz = (int)signbasedisplay(SCHAR_MAX, 10, stg, 20);

show("SCHAR_MAX ", sz, stg);

sz = (int)signbasedisplay(UCHAR_MAX, 10, stg, 20);

show("UCHAR_MAX ", sz, stg);

sz = (int)signbasedisplay(CHAR_MIN, 10, stg, 20);

show("CHAR_MIN ", sz, stg);

sz = (int)signbasedisplay(CHAR_MAX, 10, stg, 20);

show("CHAR_MAX ", sz, stg);

sz = (int)signbasedisplay(MB_LEN_MAX, 10, stg, 20);

show("MB_LEN_MAX ", sz, stg);

sz = (int)signbasedisplay(SHRT_MIN, 10, stg, 20);

show("SHRT_MIN ", sz, stg);

sz = (int)signbasedisplay(SHRT_MAX, 10, stg, 20);

show("SHRT_MAX ", sz, stg);

sz = (int)signbasedisplay(USHRT_MAX, 10, stg, 20);

show("USHRT_MAX ", sz, stg);

sz = (int)signbasedisplay(INT_MIN, 10, stg, 20);

show("INT_MIN ", sz, stg);

sz = (int)signbasedisplay(INT_MAX, 10, stg, 20);

show("INT_MAX ", sz, stg);

sz = (int)signbasedisplay(INT_MAX, 10, stg, 20);

show("INT_MAX ", sz, stg);

sz = (int) basedisplay(UINT_MAX, 10, stg, 20);

show("UINT_MAX ", sz, stg);

sz = (int)signbasedisplay(LONG_MIN, 10, stg, 20);

show("LONG_MIN ", sz, stg);

sz = (int)signbasedisplay(LONG_MAX, 10, stg, 20);

show("LONG_MAX ", sz, stg);

sz = (int) basedisplay(ULONG_MAX, 10, stg, 20);

show("ULONG_MAX ", sz, stg);

nexttest("DONE");

return 0;

} /* main */

--

Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)

Available for consulting/temporary embedded and systems.

<http://cbfalconer.home.att.net> USE worldnet address!