【问题标题】:fscanf returns 3 instead of -1 (EOF) at the end of the filefscanf 在文件末尾返回 3 而不是 -1 (EOF)
【发布时间】:2019-01-02 23:35:20
【问题描述】:

所以有一个我正在使用 fscanf() 的文件。我在我的代码中设置了一个条件,当 (fscanf(...) == EOF 时,程序需要中断我正在使用的函数目前在. 问题是, 在文件中没有更多文本行的任何情况下, 这个条件都不会满足. EOF 总是-1, 而 fscanf(...) 每次有一行代码时返回 4 , 和 3 当它没有任何东西可以搜索时(而不是 -1)。如果我添加一行与其他代码类似的代码,我将简单地获得一个 fscanf() 返回 4 的实例,然后再一次,它会给我一个 3。

可能是什么问题?提前谢谢!

示例文本文件内容:

克里斯托·乔戈斯,140,VAS。奥尔加斯 112

马拉库马拉库斯,150,德拉斯。巴加斯 12

TSIKOU GIJRAN,140,JABS。德拉加斯 1

TSIKOU BIRBAN,140,JABS。德拉加斯 1

DELHDHMHTRIOU SPYROS,50,速度。巴加斯 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);
        }
    }
}

【问题讨论】:

  • (fscanf(...) == EOF 程序需要突破的功能 --> 那是弱测试。最好针对一个期望的回报进行测试——也许像(fscanf(...) != 4。请发帖minimal reproducible example
  • 发布studentT的定义。这篇文章更好,但还不够完整,无法编译。
  • 我不确定代码的哪些部分与问题相关。我希望这有帮助。再次感谢。
  • 请提供minimal reproducible example,准确显示您如何使用fscanf(),尤其是您的实际格式字符串
  • 请注意,您的代码很奇怪。您将pApousies 作为参数传递给函数readInput,但不要使用它。您声明一个局部变量apousies 并在调用fscanf 时使用它。你对nscan == EOF 的测试在我看来没问题。

标签: c scanf eof


【解决方案1】:

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

因为最后一行缺少'\n'


OP 的代码与"tmp.txt" 一起“工作”下面的代码。

fscanf() 很难正确使用。使用fgets() 更容易编码和调试。讨论如下。


"%30[^,]" 允许太多char name[30]。使用char name[30+1]"%29[^,]"

OP 的方法很容易因看似很小的解析问题而失败,例如最后一行缺少'\n'。在这样的失败之后,fscanf() 恢复非常困难

调试:重要的是,在代码确保nscan &gt;= 4 之前,不应尝试以下打印

if (nscan >= 4) // add
  printf("onoma: %s apousies: %d sxolia: %s terma: %c\n", name, apousies,  comments, termch);

改为使用fgets()。对于方向的数据,这确实是最好的第一步。

fscanf() 难以使用和处理错误。使用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);
}

输出

Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
Success 6 <FOX SIN> 40 <BAN. NINJA 1>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 2011-08-14
    相关资源
    最近更新 更多