fscanf 不返回 EOF 或 fscanf 进入 C 中的无限循环

fscanf not returning EOF or fscanf going to infinite loop in C

我正在尝试向文件中写入几行。写入该行后,当我尝试使用 fscanf 从文件中读取这些行时,它会进入无限循环。 fprintf 正在运行,但 fscanf 将进入无限循环。

#include<stdio.h>
#include<stdlib.h>

  void main()
       {
        FILE *fp;
        int roll;
        char name[25];
        float marks;
        char ch;
        fp = fopen("file.txt","w");           
        if(fp == NULL)
        {
            printf("\nCan't open file or file doesn't exist.");
            exit(0);
        }

        do
        {
             printf("\nEnter Roll : ");
             scanf("%d",&roll);

             printf("\nEnter Name : ");
             scanf("%s",name);
             printf("\nEnter Marks : ");
             scanf("%f",&marks);

             fprintf(fp,"%d%s%f",roll,name,marks);

             printf("\nDo you want to add another data (y/n) : ");
             ch = getche();

             }while(ch=='y' || ch=='Y');

            printf("\nData written successfully...");
              
              
              
            printf("\nData in file...\n");

            while((fscanf(fp,"%d%s%f",&roll,name,&marks))!=EOF)
            printf("\n%d\t%s\t%f",roll,name,marks);
                
              

            fclose(fp);
       }

您已打开文件进行写入(模式“w”),因此您的 scanf 调用几乎肯定会失败。就算你修了模式,一点也不奇怪:

while((fscanf(fp,"%d%s%f",&roll,name,&marks))!=EOF)

进入无限循环。如果流中的下一个字符不是整数中的有效字符,则 scanf 将 return 归零并且不消耗它。它将反复尝试将该字符读取为整数并反复失败。此处正确的方法可能是完全停止使用 scanf,但快速解决方法可能类似于:

int rv;
while( (rv = fscanf(fp,"%d%s%f",&roll,name,&marks)) != EOF ){
    if( rv == 3 ){
        printf(...);
    } else {
        /* probably the right thing to do is break out of
           the loop and emit an error message, but maybe 
           you just want to consume one character to progress
           in the stream. */
        if( fgetc(fp) == EOF ){
            break;
        }
    }
}

编写 while( 3 == fscanf(...)) 并在错误输入时发出错误消息会更常见,但类似上面的 kludge 可能会有用(取决于您的用例)。

但是你需要修复打开模式。可能你只是想在写循环后关闭文件(你当然需要刷新它才能期望从文件中读取)并以模式“r”重新打开。