Home > OS >  What happens when you use scanf() for a decimal, but enter in a letter
What happens when you use scanf() for a decimal, but enter in a letter

Time:02-28

I have code that takes a number from the user, and outputs it. The thing I'm curious about is when a enter in a letter, it outputs a really high number, around 32765, sometimes more sometimes less. It seems to just choose a number randomly. My code is as follows.

#include <stdio.h>

int main(void) {
  int num;
  scanf("%d", &num);
  printf("%d", num);
  return 0;
}

Why does this happen, and is it predictable?

CodePudding user response:

Check the return value from scanf().

RETURN VALUE

On success, these functions (scanf() family) return the number of input items successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure.

So, the random values you're seeing are just the junk values which were present in num before scanf() call.

To experiment with different input combinations(valid/invalid) :

#include <stdio.h>

int main (void) {
    int num;
    char ch;
    char str[24] = ">?Junk Data?><<>?<>?";
    float fnum;

    printf ("\nNum: %d\nStr: %s\nFloat: %f\nChar: [%c]\n", num, str, fnum, ch);

    int status = scanf ("%d #s %f %c", &num, str, &fnum, &ch);
    printf ("\nStatus %d Inputs read\n", status);
    printf ("\nNum: %d\nStr: %s\nFloat: %f\nChar: [%c]\n", num, str, fnum, ch);

    // to check input buffer is intact
    // input just "TestingInputBuffer"
    status = scanf ("#s", str); //returns to read where it left-off from last call
    printf ("\nStatus: %d\nString: %s\n", status, str);

    return 0;
}

CodePudding user response:

When you call scanf("%d", &num) it reads bytes from standard input:

  1. any white space characters are ignored. This includes spaces, TABs, newlines and a few less common characters
  2. if the byte is a sign, it is consumed and remembered.
  3. then digits are consumed and converted to a value.
  4. the first non digit byte is pushed back to standard input and the value, possibly negated if there was a negative sign in front of it, is stored as an int into the location pointed to by the next argument which must be an int *.

If the first byte read for phase 3 is not a digit, it is pushed back and the conversion fails, scanf() returns the current number of successful conversion, 0 in your case.

If end if file is encountered before the first conversion can be performed, EOF is returned.

Hence if the user types A, scanf() returns 0 and num is unchanged. Since num is uninitialized, passing its value to printf for the %d conversion has undefined behavior. In your case, num happens to have a value around 32765, which gets output, but this behavior is indeed unpredictable: anything can happen, including program termination. You should always test the return value of scanf() to detect invalid or missing input and avoid undefined behavior.

Here is a modified version:

#include <stdio.h>

int main(void) {
    int num;
    if (scanf("%d", &num) == 1) {
        printf("%d\n", num);
        return 0;
    } else {
        fprintf(stderr, "invalid input\n");
        return 1;
    }
}
  • Related