char x;
scanf("%s",&x);
This is scanning a string, not a character. That means it will write the +
to x
and the \0
string terminator to some other piece of memory, which looks to be one of your variables in this case. For example, let's say your variables are laid out as follows:
Address m : x
m + 1: b with least significant byte first
m + 5: a with least significant byte first
When you scan a
and b
, the situation is as follows:
Address m : x = ?
m + 1: b = 5, 0, 0, 0
m + 5: a = 4, 0, 0, 0
Then, scanning the string +
, the situation changes to:
Address m : x = '+'
m + 1: b = 0, 0, 0, 0
m + 5: a = 4, 0, 0, 0
You'll see there that the \0
string terminator has overwritten the first byte of b
, making the resultant value zero, the exact same effect you seem to have.
Writing beyond the end of an memory of an object is undefined behaviour.
The easiest fix is probably just to scan "%c"
or " %c"
(the latter will skip any white space before reading the character) rather than "%s"
, although more robust code would use a better user input function like this one.
That's vital if you're considering scanning strings with a unbounded "%s"
(with no length limits) since there's no way to protect from buffer overflow in that case.
If you had entered something larger like MyHovercraftIsFullOfEels
, you would most likely have corrupted stack control information rather than just a small part of one local variables, and this would probably have lead to your code crashing spectacularly (or worse).
As an aside, it's also a good idea to get into the habit of checking the return value of functions that return useful information, such as scanf()
. It returns the number of items successfully scanned, which you can verify before making assumptions that prove potentially damaging, something like:
if (scanf("%d %d", &a, &b) != 2) {
fprintf(stderr, "Well, that didn't work at all\n");
exit(1);
}
// We now have two integers so carry on ...