Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting an integer to char by adding '0' - what is happening?

Tags:

c

char

I have a simple program like this:

#include <stdio.h>

int main(void)
{
    int numbers[] = {1, 2, 3, 4, 5};
    char chars[] = {'a', 'i'};
    char name[] = "Max";

    name[1] = chars[1];

    printf("name (before) = %s\n", name);

    name[1] = numbers[1];

    printf("name (after) = %s\n", name);

    return 0;
}

Compiling and running gives:

$ gcc -std=c11 -pedantic -Wall -Werror ex8_simple.c
$ ./a.out
$ name (before) = Mix
$ name (after) = Mx

Which is not what I want. I then dug up the question Store an integer value in a character array in C and changed the program like this:

name[1] = '0' + numbers[1];  //replacing  >> name[1] = numbers[1];

Then it works how I would expect:

$ gcc -std=c11 -pedantic -Wall -Werror ex8_simple.c
$ ./a.out
$ name (before) = Mix
$ name (after) = M2x

I don't understand whats happening under the hoods though, especially the version without '0' + … is really strange. Why is the string truncated in that "weird" way to Mx?

For reference, this is a simplified version of exercise 8 of Learn C The Hard Way.

like image 491
Max Avatar asked May 04 '15 11:05

Max


People also ask

What happens when you add an int to a char?

When you add a char to an int , the (p)r-value created is promoted to an int . Therefore what is printed is the int equivalent to the sum of the (usually) ASCII value + the int. The ASCII value of 'b' is 'b' == 98 . Therefore 98 + 5 == 103 (integer) .

How do I convert an int to a char?

char a = Character. forDigit(num1, 10); We have used the forDigit() method converts the specified int value into char value. Here, 10 and 16 are radix values for decimal and hexadecimal numbers respectively.

What is the integer value of the character 0?

'\0' is (like all character literals) an integer constant with the value zero.

Why you can subtract 0 from a character and have it convert to the numerical value?

All of the digit characters have values offset from the value of '0' . That means, if you have a character, let's say '9' and subtract '0' from it, you get the "distance" between the value of '9' and the value of '0' in the execution character set.


2 Answers

Each symbol has an numeric representation, so basically each char is a number. Here is the table of characters and its values.

enter image description here
(source: asciitable.com)

So, in your code name[1] = numbers[1];, you assign name[1] to 2, which is equal to symbol STX in the ASCII table above, which is not a printable character, thats why you get that incorrect output.

When you add '0' to your name[1], it is equal to add 48 to 2, so the symbol with the number 50 is '2', that's why you get that correct output.

like image 96
FalconUA Avatar answered Nov 15 '22 00:11

FalconUA


Which is not what I want.

but, you've written code for that only. Let me explain both the scenario.

  • In case of

    name[1] = chars[1];
    

name[1] or a is getting replaced with chars[1] or i. So, the o/p is Mix.

  • In case of

    name[1] = numbers[1];
    

name[1] or a is getting replaced with numbers[1] or 2, (not '2'), which is non-printable.(#note) So, the output is Mx.

However, in your second approach,

 name[1] = '0' + numbers[1];

you're storing the ASCII equivalent value of '2', by adding '0'. So, the print contains the character representation of '2' in the output.

Alternative approach:

If you modify yout int array to store the decimal equivalent of char representation of digits 0-9, then you don't need to add a '0', like

int numbers[] = {'1', '2', '3', '4', '5'};

and

name[1] = numbers[1];

will give you the desired o/p.


Suggestion : Remember, array index in C is 0 based.

# NOTE : See this ASCII table for reference.

like image 20
Sourav Ghosh Avatar answered Nov 15 '22 00:11

Sourav Ghosh