Using fscanf() vs. fgets() and sscanf()

There are a few behavior differences in the two approaches. If you use fgets() + sscanf(), you must enter both values on the same line, whereas fscanf() on stdin (or equivalently, scanf()) will read them off different lines if it doesn’t find the second value on the first line you entered.

But, probably the most important differences have to do with handling error cases and the mixing of line oriented input and field oriented input.

If you read a line that you’re unable to parse with sscanf() after having read it using fgets() your program can simply discard the line and move on. However, fscanf(), when it fails to convert fields, leaves all the input on the stream. So, if you failed to read the input you wanted, you’d have to go and read all the data you want to ignore yourself.

The other subtle gotcha comes in if you want to mix field oriented (ala scanf()) with line oriented (e.g. fgets()) calls in your code. When scanf() converts an int for example, it will leave behind a \n on the input stream (assuming there was one, like from pressing the enter key), which will cause a subsequent call to fgets() to return immediately with only that character in the input. This is a really common issue for new programmers.

So, while you are right that you can just use fscanf() like that, you may be able to avoid some headaches by using fgets() + sscanf().

Leave a Comment