Thread: Beginner C query: unexpected behaviour in programme

1. Beginner C query: unexpected behaviour in programme

Hi

I am a beginner programmer reading through the K&R C book and attempting exercises. I am writing in C and compiling in gcc on a Mac.

On one specific exercise, my solution gives unusual results in the output and I can't understand why. I've taken a look at solutions available online, but they don't indicate how i've made an error in my own code. I've also attempted debugging of sorts by putting in printf()s at various points, but that hasn't shed any light. I don't need to solve this problem, since it's purely a hobby, but I think it would be good for me to understand.

The requirement states: "write the function itob(n,s,b) that converts the integer n into a base b character representation in the string s. In particular, itob(n,s,16) formats n as a hexidecimal integer in s". I wrote code with a function itob() and then some test data in main() to check how it works.

I'll post the whole code - sorry if it's long, but I'm not sure on exactly where the error lies.

Code:
```void itob(int n,char s[],int b)
{
int i=0;
int j=0;
int m=n;
char basedigits[]="0123456789ABCDEFGHIJ";
for(i=1;pow((double)b,(double)i-1)<=m;i++)
{
s[i-1]=basedigits[n%b];
n=n/b;
}
s[i-1]='\0';

for(j=0;s[j]!='\0';j++)
;
char output[30];
for(i=0;s[i]!='\0';i++)
output[j-i]=s[i];
j++;
output[j]='\0';
for(i=0;i<=j;i++)
s[i]=output[i];
}

int main()
{
int n=0;
char s[30]="";
int b=0;
int i=0;
printf("\n\n******************\n\n");
printf("INT\t\tPWR\t\tOUT");
printf("\n\n");
itob(30,s,2);
printf("%d\t\t%d\t\t%s\n",30,2,s);
for(i=0;i<=30;i++)
s[i-1]=0;
itob(20,s,2);
printf("%d\t\t%d\t\t%s\n",20,2,s);
for(i=0;i<=30;i++)
s[i-1]=0;
itob(16,s,16);
printf("%d\t\t%d\t\t%s\n",16,16,s);
for(i=0;i<=30;i++)
s[i-1]=0;
itob(30,s,16);
printf("%d\t\t%d\t\t%s\n",30,16,s);
for(i=0;i<=30;i++)
s[i-1]=0;
printf("\n\n******************\n\n");
}```
The 2 unexpected results I find in this programme's output are:
1) the output printed by main() shows an "x" at the beginning of string s (e.g. "x10" for hexadecimal version of decimal 16)
2) the output printed by main() appears to show binary ouptut back to front (e.g. "x10100" for binary version of decimal 20)

Any comments from programmers on where I am going wrong would be much appreciated. Thanks.

2. For the first question, you never set the first (0th) index of the output variable in your function. For example, if you make this change:
Code:
`char output[30] = {'p'};`
note the output.

3. Thanks rags_to_riches I see where that's coming from. I will play around with it and see what to improve but now understand the answer to Q1.

Thanks for the input - much appreciated.

4. WARNING... untested code....
Since you are inputting integers, there's no reason to fool with doubles...

Code:
```void itob(int n,char s[],int b)
{ char digits[] = {"0123456789ABCDEF"};
int i = 0;

while (n > 0)
{ s[i] = digits[n % b];
n /= b;
i++;  }
s[i] = 0;  }```
Basically all you need is the remainder from dividing the number by the base ( n % B). That tells you wich digit you need. Then you divide the number by the base ( n/=b) and move over one space in the string (i++)... and repeat the loop until n = 0. With the digits string provided it should work for any base up to 16... although I can't imagine someone wanting a base 13 conversion...

5. 1. When you find the string's length, you have a mistake:
Code:
```for(j=0;s[j]!='\0';j++)
;
j--;```
2. 10100 is correct binary for decimal 20.

6. modwind

1) Good point - now it works.
2) I was being thick. Thanks for the correction!

Cheers