fscanf在文件末尾返回3而不是-1(EOF)

时间:2019-01-02 23:35:21

标签: c scanf eof

所以有一个文件正在使用fscanf()。我在代码中设置了一个条件,当(fscanf(...)== EOF时,程序需要脱离我所使用的函数问题是,在文件中没有更多行的情况下,永远都不能满足此条件,EOF始终为-1,而每行一行代码,fscanf(...)返回4 ,和3(没有-1可用)时,如果我添加一行与其他代码相似的代码,我将简单地再得到一个fscanf()实例,返回4,然后再次,它会给我3。

可能是什么问题?预先谢谢你!

示例文本文件内容:

CHRISTOU GIORGOS,140,VAS。 OLGAS 112

MALAKOU MALAKOS,150,DRAS。 BAGAS 12

TSIKOU GIJRAN,140,JABS。 DRALGAS 1

TSIKOU BIRBAN,140,JABS。 DRALGAS 1

DELHDHMHTRIOU SPYROS,50,速度。 BAGAS 62

FOX SIN,40,BAN。忍者1

代码:

#include <stdio.h>
#define M 100

typedef struct {
    char name[30];
    int apousies;
} studentT;

void readInput (FILE* infile, studentT students[], int *pApousies, int *pStudents);


int main()
{
    char inputfilename[30];
    FILE* infile;

    while (1) {
        printf("Input file name :");
        gets(inputfilename);

        infile  = fopen(inputfilename, "r");

        if (infile != NULL) break;
        printf("Cannot open input file %s. Try again.\n", inputfilename);
    }

    studentT students[M];
    int numberOfStudents = 0, numberOfApousies = 0;
    readInput(infile, students, &numberOfApousies, &numberOfStudents);
    fclose(infile);
    return 0;
}

void readInput (FILE* infile, studentT students[], int *pApousies, int *pStudents)
{
    int nscan, apousies, studcount, apouscount, line;
    char name[30], comments[68], termch;

    line = 0;
    while (1)
    {
        nscan = fscanf(infile, "%30[^,], %d, %68[^\n]%c", name, &apousies, comments, &termch);
       /* printf("onoma: %s apousies: %d sxolia: %s terma: %c\n", name, apousies, comments, termch);
        printf("%d\n", nscan);
        printf("%d\n", EOF);*/
        if (nscan == EOF) break; 
        line++;

        if (nscan != 4 || termch != '\n')
        {
            printf("Error in line %d. Program termination\n", line);
            exit(1);
        }
    }
}

1 个答案:

答案 0 :(得分:4)

  

fscanf在文件末尾返回3而不是-1(EOF)

因为最后一行缺少WifiManager


OP的代码与下面的代码'\n'一起使用。

"tmp.txt"很难使用。使用fscanf()更易于编码和调试。讨论如下。


fgets()对于"%30[^,]"来说允许太多。使用char name[30]char name[30+1]

OP的方法可能会因看似较小的解析问题而失败,例如最后一行缺少"%29[^,]"。发生此类故障后,使用'\n'

很难恢复

调试:重要的是,在代码确保fscanf()

之前,请勿尝试以下打印
nscan >= 4

请使用if (nscan >= 4) // add printf("onoma: %s apousies: %d sxolia: %s terma: %c\n", name, apousies, comments, termch); 。对于 line 定向数据,这确实是最好的第一步。

fgets()在使用和应对错误方面具有挑战性。使用fscanf()读取 line 并进行解析要简单得多。

使用fgets()是检测行是否已全部解析的好方法。

" %n"

样品使用

#include <stdio.h>
#include <stdlib.h>
#define M 100

typedef struct {
  char name[30];
  int apousies;
} studentT;

void readInput(FILE* infile, studentT students[], int *pApousies,
    int *pStudents) {
  (void) students;
  (void) pApousies;
  (void) pStudents;
  int line = 0;
  char buf[200];
  while (fgets(buf, sizeof buf, infile)) {
    int apousies;
    char name[30], comments[68];
    int n = 0;

    line++;
    sscanf(buf, " %29[^,],%d , %67[^\n] %n", name, &apousies, comments, &n);
    if (n == 0 || buf[n]) {
      fprintf(stderr, "Error in line %d <%s>. Program termination\n", line, buf);
      exit(1);
    }
    printf("Success %d <%s> %d <%s>\n", line, name, apousies, comments);
  }
}

输出

int main() {
  FILE *f = fopen("tmp.txt", "w");
  fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112\n"
      "MALAKOU MALAKOS,150,DRAS. BAGAS 12\n"
      "TSIKOU GIJRAN,140,JABS. DRALGAS 1\n"
      "TSIKOU BIRBAN,140,JABS. DRALGAS 1\n"
      "DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62\n"
      "FOX SIN,40,BAN. NINJA 1\n", f);
  fclose(f);

  f = fopen("tmp.txt", "r");
  studentT st[M];
  readInput(f, st, NULL, NULL);
  fclose(f);
}