I have a question about conversion specifier of scanf
in C.
#include <stdio.h>
int main(void)
{
int num1;
scanf("%hhd",&num1);
printf("%d \n",num1);
}
Since I have typed "%hhd"
as the conversion specifier in scanf
function, when my input is "128", I expect -128 to be stored in num1
. But the result shows that 128 is stored in num1
.
Why does this happen even though I have used "%hhd"
to specify input as char int
?
Step 1 With scanf()
issues: check results. Unless the return value indicates something was written into num1
, printing it does not reflect user input.
int num1;
if (scanf("%hhd",&num1) == 1) {
printf("%d \n",num1);
}
Step 2: Enable compiler warnings. Saves time.
if (scanf("%hhd",&num1) == 1) {
// warning: format '%hhd' expects argument of type 'signed char *',
// but argument 2 has type 'int *' [-Wformat=]
Why does this happen even though I have used
"%hhd"
to specify input as char int?
This in not about integer types: int
versus char
. The is about pointers: int *
versus signed char *
. "%hhd"
in scanf()
matches a pointer: signed char *
(or unsigned char *
or char *
), not an int
nor char
.
Code passed &num1
, a int *
. Compliant code would pass a signed char *
.
If a conversion specification is invalid, the behavior is undefined. C11 §7.21.6.2 13
That is it. Code broke the rules, expected behavior does not occur. Use the correct type.
signed char num1;
if (scanf("%hhd",&num1) == 1) {
printf("%d \n",num1);
}
If code must save the result in an int
:
int num1;
signed char ch1;
if (scanf("%hhd",&ch1) == 1) {
num1 = ch1;
printf("%d \n",num1);
}