Search code examples
cstdio

Why scanf accepts chars for "%f" format specifier?


I'm preparing a simple program for my classes and found that scanf is not as strict as I expected:

int main()
{
  // Define variables
  float alpha;
  float b;
  float result;

  // Get user input
  printf("Type alpha and b. Space separated float numbers only.\n");
  scanf("%f %f", &alpha, &b);
  printf("%f %f\n", alpha, b);
  return 0;
}

Returns:

Type alpha and b. Space separated float numbers only.
a 0
-29768832.000000 0.000000

Where I can read about its behavior?

How can I make input strict with standard functions and throw an exception if there was neither ints nor floats?

P. S. I'm using gcc v5 in Ubuntu.


Solution

  • I'm preparing a simple program for my classes and found that scanf is not as strict as I expected

    No, you didn't.

    Given this scanf call:

      float alpha;
      float b;
    
      scanf("%f %f", &alpha, &b);
    

    ... and this input:

    a 0
    

    ... scanf has a matching failure when it encounters the 'a' while trying to scan a floating-point value and not having yet scanned any decimal digits. It stops at that point (and leaves the 'a' in the stream for a subsequent read), and, as always, it returns the number of input fields successfully scanned (0).

    Where I can read about its behavior?

    You could try running the command man scanf at the command line (Linux, OSX, ...), or entering the same as a Google search. Or google "scanf docs" or "scanf manual" or similar. Or look up the official manual for your particular C library. For standard library functions, the standard is an excellent reference, but your particular implementation may have extensions not documented there, or occasionally may even differ from the standard in minor ways.

    How can I make input strict with standard functions and throw an exception if there was neither ints nor floats?

    C does not have exceptions. It tells you about errors via function return values, for the most part, though some third-party libraries may do it slightly differently. But you have to do your part, by checking the return values and responding appropriately. In this particular case, you must avoid reading the values of alpha and b. Because those variables were not initialized and did not subsequently have any values assigned to them, reading their values produces undefined behavior.