tags:

views:

102

answers:

2

Why does this not work as expected?

int main()
{
    unsigned char louise, peter;

    printf("Age of Louise: ");
    scanf("%u", &louise);

    printf("Age of Peter: ");
    scanf("%u", &peter);

    printf("Louise: %u\n", louise);
    printf("Peter: %u\n", peter);

    return 0;
}

Outputs:

Age of Louise: 12
Age of Peter: 13
Louise: 0
Peter: 13

But if I swap variable declarations it works:

unsigned char peter, louise;

Outputs:

Age of Louise: 12
Age of Peter: 13
Louise: 12
Peter: 13

I've also noticed that using int or unsigned int works without needing to swap variables, but chardoesn't.

I've tried putting printf("%u", louise); just after the scanf() for louise and the value is saved correctly. And if I comment out the second scanf() it also works fine...

The "problem" shows on Windows (DevCpp) and Linux (kwrite + make). Is that a bug of the compiler, or mine?

+3  A: 

Because %u reads and stores an unsigned int, which is very likely larger than the single unsigned char you have. This leads to adjacent values being overwritten.

There is no way to read an integer string (such as "42") and store it in a char. You must go via an int. Example:

int tmp;
char my_char;

if(scanf("Enter a number: %d", &tmp) == 1)
{
  my_char = (unsigned char) tmp;
}
unwind
Yeah! That must be. Thanks!
xOneca
Oh, thanks for the sample code!
xOneca
A: 

That is your bug, your variables were of type unsigned char which is 1 byte, however, you entered 12 which is 4 bytes (a unsigned int), that caused an overflow (implementation defined by the compiler/runtime), and that would explain it overwriting the next variable in memory. You used the %u specifier for printf which is an unsigned int, for a unsigned char variable, that is incorrect and does not match up. That explains, as you have discovered yourself, that using an unsigned int or int works, as there was sufficient room to hold the values on input.

Hope this helps, Best regards, Tom.

tommieb75
Oh! Now I get it! Thanks!How do I make to get a number to a `char` with `scanf()`? Or I have to declare them integer?
xOneca
@xOneca: declare them as integer. Why did you use unsigned char anyway? :)
tommieb75
because I know nobody older than 255 years. I am used to use the smallest variable I can, to save memory. I see I can't do that always... :-(
xOneca
@xOneca: that's ok. That's a healthy attitude..that would have been the attitude 15-20 years ago...now pc's have a lot of memory...but still a good approach to squeezing a few more bits... :)
tommieb75