views:

269

answers:

4

I have done a lot with Java but I am currently trying to learn c. I am trying to make a program to convert a number from decimal to binary.

Here is what I have:

#include <stdio.h>
#define LENGTH 33

int main( int argc, char*argv[ ] )

{
 unsigned int number, base, remainder, x, i;
 char result[LENGTH];

 puts( "Enter a decimal value, and a desired base: " );
 scanf( " %u", &number );
 scanf( " %u", &base );

 x = number;

 for( i=0; i < LENGTH; i++ )
 {
  remainder = x % base;
  x = x/base;
  result[i] = remainder;
 }

 printf( "%u equals  %s  (base-%u) \n", number, result, base );    

 //***result is probably backwards...


 return 0;



}

And here is what I get when I run it:

Enter a decimal value, and a desired base: 
5 2
5 equals    (base-2)

What is the square and how to I get it to display as a string (char array)?

+4  A: 

Last Edit: Your program might look like the following:

 unsigned int number, base, remainder, x, i;
 char result[LENGTH+1] = {0};

 puts( "Enter a decimal value, and a desired base: " );
 scanf( " %u", &number );
 scanf( " %u", &base );

 x = number;

 for( i=0; i < LENGTH; i++ )

 {
  // if base > 10, use alphabet!
  result[i] = remainder > 9 ? (remainder-10) + 'A' : remainder + '0';
  x = x/base;
  result[i] = remainder + '0';
 }


First, when writing the remainder, you should add the ASCII offset of the digit.

  result[i] = remainder + '0';

Also, you forgot to add'\0' at the end.

 result[i] = 0;
 printf( "%u equals  %s  (base-%u) \n", number, result, base );


EDIT: When writing to a c-string, I usually initialize the string to zeros:

char result[LENGTH] = {0};

This way you don't need to write the null character at the end , it is written for you.


Thanks @mmyers for pointing out the overflow :) I would declare the string to hold LENGTH+1:

char result[LENGTH+1] = {0};
AraK
+1 - I forgot about the '\n', didn't notice the omission.
James Black
Note this solution is unlikely to work properly for bases larger than 10, since in general 10 + '0' != 'a' (or 'A'). It certainly doesn't work in ASCII.
Pillsy
`result[i] = 0` is out-of-bounds since the loop just incremented i to LENGTH.
Michael Myers
@Pillsy I think we need more code to handle hex :)
AraK
@AraK: Not really. Did you see Pillsy's answer?
Michael Myers
+1  A: 

You need to ensure that your string has values between 32 and 127 to be displayed on a terminal.

for( i=0; i < LENGTH; i++ )

 {
  remainder = x % base;
  x = x/base;
  result[i] = remainder;
 }

In this section you are putting small values into the array, so it won't show up as ASCII letters.

You may just want to have something like: result[i] = remainder + '0';

An easy way to see is to print out the ascii value of each part of the string and see what value is.

James Black
+4  A: 

You want to store a digit as a character in result[i], rather than the actual number that's the remainder. One way to do this, for bases up to (say) 16, is to index into an auxiliary array (which can be a string literal) that has the digits you want.

char digits[] = "0123456789ABCDEF";

/* stuff */

result[i] = digits[remainder];

/* more stuff */

Also, the other comments that are telling you to null terminate your string are entirely correct.

EDIT: Whichever route you go, you should ensure that the value input for base is greater than 0 and not greater than whatever maximum you wish to handle.

Pillsy
+1 for the digit table, which I stole without realizing it.
Michael Myers
+1 the idea of digits array is really better than a ternary operator ;)
AraK
A: 

Is this an academic exercise? If not many C compiler libraries include the itoa() function that does exactly what you need. It is not defined by the ISO standard C library, but is commonly included in most compilers.

Clifford