Reputation: 99
Text editor : VS code
Compiler : minGW
I was needed to store a number between 1-10, so I thought why don't store it in a char variable because it takes only 1 byte.
so, look at the following code
char a = 3;
printf("%d", a);
OUTPUT
3
it worked fine
Then I decided to take value as input using scanf
Here's the code for that
char a;
printf("Enter number : ");
scanf("%d", &a);
printf("You entered : %d", a);
OUTPUT
Enter number : 9
You entered : 9
It worked fine too, but problem lies when I tried with two variables
Look at the the code below
char a = 2, b = 3;
printf("before scanf a : %d\n", a);
printf("before scanf b : %d\n", b);
printf("Enter new value of a : ");
scanf("%d", &a);
printf("after scanf a : %d\n", a);
printf("after scanf b : %d\n", b);
OUTPUT
before scanf a : 2
before scanf b : 3
Enter new value of a : 9
after scanf a : 9
after scanf b : 0 //Notice value of b has changed to 0
Even though, I didn't even touched b's value. still it changed. . I tried a lot to figure it out but failed, I'm a beginner. I think it's something to do with stdin/out stream. please help me here..
Upvotes: 0
Views: 687
Reputation: 2275
The format specifier %d
specifies int, not char. When you use this format specifier with printf
and pass a char, this doesn't really matter because char gets implicitly promoted to an int.
But with scanf, you end up passing a char pointer (note that scanf
uses &a
instead of simply a
) where scanf
expects an int pointer. Hence scanf
ends up copying an int into a char, which means that data spills over into the adjacent memory location(s). In your case, this adjacent location happens to be the variable b
, thus the value of b
gets overwritten with the MSB of the integer that is input, which in this case is 0.
PS: I should also mention the fact that you shouldn't really rely on this behaviour. What I mentioned above is the most likely explanation for your observation. This particular scenario falls under undefined behaviour so a different compiler, different hardware or a different run of the same program could theoretically have resulted in a drastically different outcome and it would still be perfectly legal! The proper solution is to use an int instead of a character. On a modern machine, you are not saving much anyway with these antics.
Upvotes: 1
Reputation: 11
What's happening is that your program thinks a is of type int. Since the size of an int is 4 bytes, if you do:
char a = 2, b = 3, c = 4, d = 5, e = 6;
scanf("%d", &a)
will corrupt the values of b, c, d (but will not corrupt the value of e, because e is the 5th byte, and the size of int is 4), because scanf thinks that you've passed a pointer to an int, not to a char.
Upvotes: 0
Reputation: 222302
scanf("%d", &a);
instructs scanf
to read a decimal numeral and assign it to an int
pointed to by &a
. Since &a
points to a char
, not an int
, the behavior is not defined by the C standard.
Proper code is to declare a
as a signed char
and use scanf("%hhd", &a);
. (Technically, there is no conversion specifier to assign to a char
.)
Upvotes: 1