feof detecting false end of file

2019-09-17 11:15发布

问题:

I asked a different question about this earlier, but I was way off base about the problem so I've created a new question as I'm asking an entirely different question.

I have a function that reads a given line in a text file (given by ac variable). It performs the read of the line and then checks if that was the last line in the file. If so it increments a value.

The problem is that it's incremented the value even when it's not the actual end of the file. I think I'm using feof wrong but I've had no luck getting it to work:

int readIn(TinCan* inCan, int toggle)
  {
  int ii, isFinished = 0;
  char fullName[20];
  sprintf(fullName, "Label_%d.txt", inCan->pid);

  FILE* fp; 
    fp = fopen(fullName, "r");

    if(fp==NULL) 
      {
      printf("Error: could not open %s\n", fullName);
      }

    else
      {
      for (ii=0; ii < ((inCan->ac)-1); ii++)
        {
        fscanf(fp, "%*d %*d %*d\n"); /*move through lines without scanning*/
        }
      fscanf(fp,"%d %d %d", &inCan->ac, &inCan->state, &inCan->time);
      }

    if (feof(fp) && (toggle == 1)) 
      {
      printf("File ended"); 
      writeLog(inCan);
      isFinished = 1;
      terminated++;
      }

  fclose(fp);
  return finished;
  }

Sample data as requested, this is a text file I may use:

1 1 30
2 2 5
3 1 1

fscanf correctly assigns the values. On the second line, feof returns true and terminated is incremented. feof returns true again for the 3rd line and increments terminated a second time.

回答1:

feof() does not detect if the file has ended. It detects if the last read error was due to the file having ended.

feof() only happens after a failed read.

So, first read data and check the return value. If the read failed use feof() to make sure it failed because the END-OF-FILE was reached (other reasons for the read to fail are error of some kind (network down, bad sector, printer on fire, ...), detectable with ferror()).



回答2:

It's hard to tell without knowing the data format, but

 fscanf(fp,"%d %d %d", &inCan->ac, &inCan->state, &inCan->time); 

will read 3 values, but on the last line, it won't have read the end of line character, so it's not the end of the file.

Try:

 fscanf(fp,"%d %d %d\n", &inCan->ac, &inCan->state, &inCan->time);


标签: c scanf feof