Which file readers in C can handle reading an inconsistent file? Sometimes the file is "word number" and other times it is just "word". Like this.

bob 456
echo
cat 
dog 1101
peacock 300

This is what I tried with fscanf. I am surprised it worked. I didn't think fscanf liked inconsistent files. Is there something I need to be worried about? I know fscanf has really bad side effects if you are not careful.

while (fscanf(pFile, "%s %d",  nam, &val) !=EOF)
{
    //my work
}

You will be reading some numbers as strings, some strings as numbers, and you have no way of telling if you're meant to be reading a string or a number.

You need to read every word as a string, examine it, and do whatever is appropriate if it's actually a number.

A better approach would be to read a line at a time and parse each line looking for the format you describe.

Sometimes the file is "word number" and other times it is just "word".

That's actually very consistent. All you need to do is look for two potential line cases, which is easy:

while (fgets(line, sizeof line, pFile) != NULL)
{
    int items = sscanf(line, "%s %d", nam, &val);

    if (items == 1)
    {
        // Just a word
    }
    else if (items == 2)
    {
        // Word and number
    }
    else
    {
        // Error (probably a blank line)
    }
}

Is there something I need to be worried about?

The return value of fscanf is the number of items extracted. EOF is only returned when end of file is reached without extracting any items. Especially when reading a file format line by line with fscanf, you should be careful to make sure that your extraction doesn't accidentally span lines. Using EOF as the loop condition increases the risk of that happening. For strict formats, I strongly recommend checking for the number of extraction specifiers in your format string. For example, if you're extracting two items, test the result for 2:

while (fscanf(pFile, "%s %d", nam, &val) == 2)
{
    ...
}

If you can't follow that pattern, fscanf's return value shouldn't be used for the outer loop condition because making it work can get kind of hairy.

You'll notice that in my example I used fgets to read a single line, then sscanf to parse it. Further, I carefully checked the return value. This is a recommended approach when your lines are reasonably well formatted.

This article has been dead for over six months. Start a new discussion instead.