How do we test the return values from the scanf() function?

c, scanf

Solution

`scanf()` et al return the number of successful conversions.

If you have:

scanf("%f", &f);

you should test:

if (scanf("%f", &f) == 1)
    ...all OK...
else
    ...EOF or conversion failure...

If you have several conversions, check that they all completed. If you're using `%n` 'conversions', they aren't counted.

Although `scanf()` does return EOF on EOF, you should not test for that — you should always check primarily that you got the number of conversions you expected. For example, consider the buggy code:

while (scanf("%f %d %s", &f, &i, s) != EOF)  // Here be BUGS!
    ...loop body...

If you type `3.14 x23 yes`, then you will have an infinite loop because `scanf()` will return 1 on the first iteration (it successfully converted 3.14), and 0 thereafter (not EOF).

You might be OK with:

while ((rc = scanf("%f %d %s", &f, &i, s)) != EOF)
{
    if (rc != 3)
        ...oops data problems...
    else
        ...all OK...
}

Judging from previous questions, you should be looking at using `fgets()` (or possibly POSIX `getline()`) to read lines of data, and then using `sscanf()` or even functions like `strtol()` and `strtod()` to read particular values from the line. If you use `sscanf()`, the comments made above about checking the number of successful conversions still apply.

I don't use `scanf()` in production code; it is just too damn hard to control properly. I regard it as almost suitable for beginning programs — except that it causes lots of confusion. On the whole, the best advice is 'stay clear of `scanf()` and `fscanf()`'. Note that that does not mean you have to stay clear of `sscanf()`, though some caution is needed even with `sscanf()`.

Problem

I want to confirm if a value returned from the `scanf()` function is a floating number or not. How can I do that? My code is not running as it should if the wrong data types are supplied to the `scanf()` function. Similarly, how would I confirm if a value returned is a character string or not?

Original source