-1

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?

alk
  • 69,737
  • 10
  • 105
  • 255
Jin
  • 1,902
  • 3
  • 15
  • 26
  • 4
    Looks like undefined behavior to me. โ€“ melpomene Jul 22 '16 at 08:06
  • Possible duplicate of [Converting an int to char using printf](http://stackoverflow.com/questions/13595628/converting-an-int-to-char-using-printf) โ€“  Jul 22 '16 at 08:17
  • `%hhd` specifies that the pointer should be treated as "the next pointer is a pointer to a signed char or unsigned char." This means that (if CHAR_BITS is 8, not an unreasonable assumption) that either 128 or -128 are perfectly valid results. โ€“ Vatine Jul 22 '16 at 09:06

1 Answers1

2

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);
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256