When / why is it a bad idea to use the fscanf () function?

An interesting expression appeared in the response : "It is almost always bad to use the fscanf() function, since it can leave the file pointer an unknown place to refuse. I prefer to use fgets() to get each line, and then sscanf() ."

Could you tell me when / why it is better to use fgets() and sscanf() to read some file?

+6
c pointers file-io
source share
6 answers

Imagine a file with three lines:

  1 2b c 

Using fscanf() to read integers, the first line will read fine, and in the second line fscanf() will leave you at 'b', not knowing what to do next. You will need some kind of mechanism to move around the garbage inlet to see the third line.

If you do fgets() and sscanf() , you can ensure that the file pointer moves the line at a time, which is a little easier to handle. In general, you should still look at the entire string to report any odd characters in it.

I prefer the latter approach myself, although I would not agree with the statement that "it is almost always a bad idea to use fscanf() " ... fscanf() great for most things.

+13
source share

The case where this comes into play is when you match alphabetic characters. Suppose you have:

 int n = fscanf(fp, "%d,%d", &i1, &i2); 

Consider the two possible inputs " 323,A424 " and " 323A424 ".

In both cases, fscanf() will return 1, and the next character read will be 'A' . It is not possible to determine if a comma matches or not.

Saying this, it matters only in order to find the actual source of the error. In cases where it is known that an incorrect input error exists, fscanf() actually superior to writing user parsing code.

+4
source share

When fscanf () fails due to input failure or a corresponding failure, the file pointer (i.e. the position in the file from which the next byte will be read) remains at a position different from where it would be if fscanf () succeeded. This is usually undesirable when reading files sequentially. Reading one line at a time leads to the fact that the input file is predictable, and single failures can be processed individually.

+2
source share

There are two reasons:

  • scanf() may leave stdin in a state that is difficult to predict; this makes error recovery difficult, if not impossible (this is less of a problem with fscanf() ); and
  • The entire scanf() family accepts pointers as arguments, but does not limit the length, so they can intercept the buffer and change the unrelated variables that occur after the buffer, causing seemingly random memory corruption errors that are very difficult to understand, find, and debug , especially for less experienced C programmers.

C beginners often get confused about pointers and the address-of operator and often omit & where necessary, or add it "for good measure" where it is not. This leads to โ€œrandomโ€ segfaults, which can be difficult for them. This is not a scanf() error, so I leave this on my list, but it is worth keeping in mind.

After 23 years, I still remember that it was a huge pain when I started programming in C and did not know how to recognize and debug such errors, and (like someone who spent years teaching C to beginners), it is very difficult to explain them to beginners who don't understand pointers and stack yet.

Anyone who recommends scanf() novice C programmer should be mercilessly destroyed.

OK, maybe not mercilessly, but some kind of flogging is definitely in order: o)

+2
source share

It is almost always a bad idea to use the fscanf() function, since it can leave the file pointer in an unknown location if it fails. I prefer to use fgets() to get each line, and then sscanf() .

You can always use ftell() to find out the current position in the file, and then decide what to do next. Basically, if you know what you can expect, then feel free to use fscanf() .

+1
source share

In principle, there is no way to say that the function does not go beyond the memory area that you allocated for it.

Several replacements have appeared, for example, fnscanf, which try to fix these functions by indicating the maximum reading limit for the reader, which allows it to not overflow.

0
source share

All Articles