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.
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) .
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.
'\0' is (like all character literals) an integer constant with the value zero.
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.
Each symbol has an numeric representation, so basically each char is a number. Here is the table of characters and its values.
(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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With