... I understand that passing a pointer to a double to scanf when
it expects a pointer to a float would be an error, but even if in the
example above val is declared type float won't the call to scanf
truncate any value entered to a float? For instance if I have the
following code snippet
unsigned int num;
printf("\nEnter number: ");
scanf("%i",&num);
printf("\nThe answer is: %i\n", num);
If on a 32 bit machine the user enters 4294967300 The answer printed
would be 4? Will errno be set to ERANGE? I can not see that it is. Or
is there some other way to test that this overflow condition occured?
The scanf() function family should in general not be used on
"non-sanitized" input. (Certain formats can be used, especially
if you are Dan Pop
, on certain streams with reasonable
safety.)
In particular, scanning 4294967300 with %i format gives undefined
behavior. In *my* stdio, the %i conversion actually uses strtol(),
so that you will get 2147483647 on a 32-bit-int machine with errno
set to ERANGE. (Note that %i expects a pointer to a *signed* int,
not an unsigned one.) On other systems, however, you will indeed
get the result described above.
If you have the sequence "4294967300" (including terminating '\0'
character) in an array, however, you can write:
unsigned long result;
result = strtoul(that_array, NULL, 10);
to force a base-10 conversion of the numeric value, with clamping
at ULONG_MAX. (Set base to 0 for a %i-like prefix-determines-base
conversion.) Note that strtoul() allows leading "-" prefixes;
if you wish to prohibit those, you must check the input yourself.
Reading arbitrary user input is one of the most difficult things
to do in C, or indeed in many other languages. The problem is not
so much the language -- although C often makes it unusually easy
to get something wrong here -- but rather with the fact that humans
find such inventive ways to present your program with unexpected
input. For instance, the five-year-old might hold down the 'b'
key (or drop a sausage on it) until it has repeated several hundred
thousand times.