I was using gcc and was testing various ways to process characters using either integers or characters as the datatype.
int main() {
int i;
printf("Enter a char: ");
scanf(" %c", &i);
printf("integer value= %d char value=%c", i, i);
return 0;
}
Output:
Enter a char: f
integer value= 4198 char value=f
I am curious about the integer value that is stored. It looks like the value is equal to 4096 + ascii value of 'f'.
My question is why is 4096 added to the ascii value of the character? What does that value represent?
Type in the following program and you'll understand why:
#include <stdio.h>
int main (void) {
int val = 4096;
printf ("Enter your character: ");
scanf ("%c",&val);
printf ("integer val = %d, character val = %c\n", val, val);
return 0;
}
Compiling this with gcc -Wall
(all warnings), gives:
qq.c: In function 'main':
qq.c:6: warning: format '%c' expects type 'char *',
but argument 2 has type 'int *'
(as good a reason as any for ensuring you enable all warnings when compiling) and running it gives the same results you found:
Enter your character: f
integer val = 4198, character val = f
The reason for this is the way scanf
works combined with the way variables are laid out in memory.
That scanf
will simply get a character and put it in memory. Because you've given it the address of an integer, and that integer is little-endian, it will only overwrite the least-significant byte (LSB) of that integer. Think of viewing that memory as an overlapped area and you'll see why:
+--- The address passed to scanf.
|
V
+------+
| char | <-- Treated as char.
+------+------+------+------+
| lsb | | | msb | <-- Treated as integer (assumes 32-bit).
+------+------+------+------+
Because scanf
doesnt touch those rightmost bytes of the integer, they're left with whatever they held before the call. In my code, I explicitly force that to 4096
but, if your declaration is the uninitialised int val;
, the contents will be indeterminate. In fact, when I remove the initialisation, I get 1629542246
(0x6120D766
and you can still see the LSB set to 0x66
or f
).
That just means my integer looked like this before the scanf
call:
+------+
| ?? |
+------+------+------+------+
| ?? | d7 | 20 | 61 |
+------+------+------+------+
and the scanf
call only changed the ??
bit.
Are you initializing the int before reading in the char? Could simply be an uninitialized value.
Can you show the code? What function are using the read the character into the int?
4096 is 0x00001000 in hex. Could be a flag or something before or after the character, or the number of characters read, depending on what you are using to read the character.