having problem with this code for hex/binary conversion
Author Message
having problem with this code for hex/binary conversion

Here is program source code I picked from programing in ANSI C by Stephen Kochan
I am new to programming and I had a difficult time debugging this program

This below program converts a number to binary and also hex.
I am not understanding the logic of this code, and why is not running
It compiles ok, and ask for a number and base(2 or 16),
but doesnt convert.
It seems that do/while loop is having problems
I would appreciate the help, I have spent three days going through this

thanks in advance. I dont want a new code I need this one to work.
I am using Borland compiler and also Visual C++ compiler none of them work.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#include <stdio.h>
void main()
{
char base_digits[16] =
{'0', '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int converted_number[64];
long int number_to_convert;
int next_digit, base, index=0 ;

// get the number and the base

printf(" Number to be converted\n");
scanf("%ld", &number_to_convert);
printf("BASE ?\n");
scanf("%d", &base);

// convert to the indicated base

do
{
converted_number[index] = number_to_convert % base;
++index;
number_to_convert = number_to_convert / base;

Quote:
}

while (number_to_convert !=0);

//DISPLAY THE RESULTS IN REVERSE ORDER

printf(" Converted number = ");
for(index; index >= 0; --index)
{
next_digit = converted_number[index];
printf("%c", base_digits[next_digit]);

Quote:
}
printf("\n");
}

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Tue, 23 Nov 2004 22:00:21 GMT
having problem with this code for hex/binary conversion
Le vendredi 07 juin 2002, 16:00:21,

dans comp.lang.c :

Quote:
> Here is program source code I picked from programing in ANSI C by
> Stephen Kochan I am new to programming and I had a difficult time
> debugging this program

> This below program converts a number to binary and also hex.
> I am not understanding the logic of this code, and why is not
> running It compiles ok, and ask for a number and base(2 or 16),
> but doesnt convert.
> It seems that do/while loop is having problems
> I would appreciate the help, I have spent three days going through
> this

> thanks in advance. I dont want a new code I need this one to work.
> I am using Borland compiler and also Visual C++ compiler none of
> them work.

> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> #include <stdio.h>
> void main()
> {
> char base_digits[16] =
> {'0',
> '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; int
> converted_number[64]; long int number_to_convert;
> int next_digit, base, index=0 ;

> // get the number and the base

> printf(" Number to be converted\n");
> scanf("%ld", &number_to_convert);
> printf("BASE ?\n");
> scanf("%d", &base);

> // convert to the indicated base

> do
> {
> converted_number[index] = number_to_convert % base;
> ++index;
> number_to_convert = number_to_convert / base;
> }
> while (number_to_convert !=0);

Once you're here, index will point to the first free space in
converted_number. i.e. if the conversion generates 5 digits, the
numbers corresponding to the digits will be in converted_number[0] to
converted_number[4], and index = 5.

Quote:
> //DISPLAY THE RESULTS IN REVERSE ORDER

> printf(" Converted number = ");
> for(index; index >= 0; --index)
> {
> next_digit = converted_number[index];
> printf("%c", base_digits[next_digit]);
> }
> printf("\n");
> }
> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

There, you start to access converted_number[index] while index is
still 5 (in my example). You need one change:

for (--index; index >= 0; --index)
^^
decrement index at the beginning.

The '--index' you already have is applied at the end of each loop
iteration.

Another possible rewrite is:

while (index > 0)
{
--index;
next_digit = converted_number[index];
printf("%c", base_digits[next_digit]);

Quote:
}

--
___________
_/ _ \_`_`_`_)  Serge PACCALIN -- sp ad mailclub.net
\  \_L_)   Il faut donc que les hommes commencent
-'(__)   par n'tre pas fanatiques pour mriter
_/___(_)    la tolrance. -- Voltaire, 1763

Tue, 23 Nov 2004 22:21:01 GMT
having problem with this code for hex/binary conversion

Quote:

>  Here is program source code I picked from programing in ANSI C by
>  Stephen Kochan

If this program really comes from a book, don't use that book; it
teaches incorrect things.

Quote:
>  void main()

The main function must return int: use int main(void) at the beginning
of the function definition and return 0; as the last statement in the
main function.

Quote:
>  scanf("%ld", &number_to_convert);

This use of scanf is dangerous. You should always check its return value
and use field widths to avoid overflow.

Gergo
--
There's small choice in rotten apples.
-- William Shakespeare, "The Taming of the Shrew"

Tue, 23 Nov 2004 22:31:33 GMT
having problem with this code for hex/binary conversion

Quote:
> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> #include <stdio.h>
> void main()

int main.

Quote:
> {

You should be indenting code - it's hard to read if you don't. Pick
a plausible style and stick to it.

Quote:
> char base_digits[16] =
> {'0', '1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
> int converted_number[64];

Note that all the elements of this array are garbage.

Quote:
> long int number_to_convert;
> int next_digit, base, index=0 ;

> // get the number and the base

Preferable to use /* */ comments - not all compilers support C99, and
wrapped // comments make code harder to cust-paste-compile.

Quote:
> printf(" Number to be converted\n");
> scanf("%ld", &number_to_convert);
> printf("BASE ?\n");
> scanf("%d", &base);

Quote:
> // convert to the indicated base

(ditto re comment)

Quote:

> do
> {
> converted_number[index] = number_to_convert % base;
> ++index;
> number_to_convert = number_to_convert / base;
> }
> while (number_to_convert !=0);

`index` refers to the element after the last one updated.

Quote:
> //DISPLAY THE RESULTS IN REVERSE ORDER

> printf(" Converted number = ");
> for(index; index >= 0; --index)
> {
> next_digit = converted_number[index];

So here, on the first iteration, `index` refers to the element
after the last one updated, which is garbage (because it's an
uninitialised automatic variable), so `next_digit` gets a
garbage value ...

Quote:
> printf("%c", base_digits[next_digit]);

... which might be bad for indexing `base_digits`. I added a little
diagnostic print to your code [a straightforward debugging tactic]
and got:

Number to be converted
99
BASE ?
2
* convert 99 to base 2
* -- got here
* index 7, digit 134513012

You'll see that the index digit is a little on the large side.
(That's my local garbage: yours will probably be different.)

You need to pre-decrement the index in the output loop: I'd
suggest

while (index > 0)
{
next_digit = converted_number[--index];
...
}

rather than using a for-loop.

Quote:
> }
> printf("\n");

return 0;

Quote:
> }
> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html

Tue, 23 Nov 2004 22:35:37 GMT
having problem with this code for hex/binary conversion

Quote:

>> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
>> #include <stdio.h>
>> void main()

> int main.

Gosh, that looks confusing now I reread it. I mean that main returns
int, not void, so you should write

int main(void)

[1], not that you should write "int main.".

[1] Or the `int main(int argc, char **argv)` etc form(s), but the OPs
code doesn't appeal to the command line.

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html

Tue, 23 Nov 2004 22:41:05 GMT
having problem with this code for hex/binary conversion

Quote:

> Here is program source code I picked from programing in ANSI C by
> Stephen Kochan I am new to programming and I had a difficult time
> debugging this program

> This below program converts a number to binary and also hex.
> I am not understanding the logic of this code, and why is not
> running It compiles ok, and ask for a number and base(2 or 16),
> but doesnt convert.

Try this:

/* 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;

Quote:
} /* 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]);

Quote:
} /* 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);

Quote:
} /* 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;

Quote:
} /* signbaseddisplay */

/* ==================== */
/* flush to end-of-line */
int flushln(FILE *f)
{
int ch;

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

Quote:
} /* 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);

Quote:
} /* 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);

Quote:
} /* 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);

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;

Quote:
} /* main */

--

Available for consulting/temporary embedded and systems.

Wed, 24 Nov 2004 03:41:21 GMT
having problem with this code for hex/binary conversion

[snip]

Quote:
>    size_t lgh;

Short for lighp? :-)

Quote:
> ...
> /* ========================= */
> /* 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);

Why not simplify with

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

or

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

[snip]

Quote:
> static void show(char *caption, int sz, char *stg)
> ...

Why not size_t for sz?

Quote:
>    if ((unsigned)sz != strlen(stg))

It would avoid this cast for one.

Quote:
> ...
> int main(void)
> {
> ...
>    int          sz;
> ...
>    sz = (int)basedisplay(VALUE, base, stg, LGH - 1);

Again, why not size_t for sz and avoid all those (int) casts?

--
Peter

Wed, 24 Nov 2004 21:17:16 GMT
having problem with this code for hex/binary conversion

Quote:

> [snip]

> >    size_t lgh;

> Short for lighp? :-)

??? I don't get it.

... snips ...

Quote:

> Again, why not size_t for sz and avoid all those (int) casts?

Once it is correct, I am not really worried about minor
reductions.  In particular most casts don't even involve
generating any code whatsoever.  The argument for reorganizations
is that casts are innately error prone, not typing reduction.

--

Available for consulting/temporary embedded and systems.

Thu, 25 Nov 2004 03:16:41 GMT
having problem with this code for hex/binary conversion

Quote:

[snip]
> > Again, why not size_t for sz and avoid all those (int) casts?

> Once it is correct, I am not really worried about minor
> reductions.

Quote:
> In particular most casts don't even involve
> generating any code whatsoever.

That's no excuse!

Quote:
> The argument for reorganizations
> is that casts are innately error prone, not typing reduction.

Correct. Typing reduction!? What...?

--
Peter

Thu, 25 Nov 2004 15:34:17 GMT
having problem with this code for hex/binary conversion
Guys
What happened to my question
I have tried everything, nothing works
I guess the basic code is wrong.

thanks

Quote:

>  [snip]
> > > Again, why not size_t for sz and avoid all those (int) casts?

> > Once it is correct, I am not really worried about minor
> > reductions.

> Sir, what about maintenance? :)

> > In particular most casts don't even involve
> > generating any code whatsoever.

> That's no excuse!

> > The argument for reorganizations
> > is that casts are innately error prone, not typing reduction.

> Correct. Typing reduction!? What...?

Fri, 26 Nov 2004 21:00:49 GMT
having problem with this code for hex/binary conversion

Quote:
> Guys

and dolls?

Quote:
> What happened to my question

It was answered, several posts ago.

Quote:
> I have tried everything, nothing works

Then you haven't tried the fix I suggested. I tried it on your code
here, and it worked.

Quote:
> I guess the basic code is wrong.

No.

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html

Fri, 26 Nov 2004 21:14:39 GMT
having problem with this code for hex/binary conversion

Quote:

> What happened to my question
> I have tried everything, nothing works
> I guess the basic code is wrong.

Don't toppost.  Do quote.  Do snip *immaterial things*.

I see no question except "what happened". Basic is OT on c.l.c.

--

Available for consulting/temporary embedded and systems.