Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do we need to clear the scanf buffer?

Tags:

c

scanf

I always thought that the "'\n' in buffer" issue only occurs when we are reading characters, however, I stumbled upon this issue with the following code:

int main(int argc, char** argv){
    int height = 0, width = 0;

    while(height < 1 || height > 10|| width < 1 || width > 15){
        printf("Please insert the height(1~10) and width(1~15) of the parallelogram (integers): ");
        if(scanf("%d %d", &height, &width) != 2){
            height = width = 0;
        }
    }
    return 0;
}

As above, I'm only reading integers with scanf, but this piece of code still gets stuck in an infinite loop when I input something invalid. It's fixed if I clear up the buffer.

So my question is, is this "'\n' in buffer" issue a general thing? Or does it only happen for special usages? If it only happens for special usages, is there some general guideline I need to follow?

like image 790
nancyheidilee Avatar asked Sep 04 '15 08:09

nancyheidilee


1 Answers

The general guideline is to not use *scanf() for user input. Your capabilities to recover gracefully from ill-formatted input are just too limited, the chance of errors too high (as can be seen by the sheer amounts of *scanf()-related questions here on SO). The *scanf() function family is best used for reading well-formatted input only (i.e. data that was previously written by your own application).

User input is line-based anyway, at least if you're relying on standard input functions.

So use fgets() to read a full line of input, then parse it in-memory. Functions like strtol() or strtod() can give very specific feedback at which point exactly they stopped parsing, you can skip back and try a different parse, you have all the string-handling functions of the standard at your disposal to pick apart your user's input. And if things go pear-shaped, you can repeat the whole line of input in your error message, adding whatever information on your parsing attempts you like.

like image 178
DevSolar Avatar answered Nov 11 '22 10:11

DevSolar