【问题标题】:fscanf not returning EOF or fscanf going to infinite loop in Cfscanf 不返回 EOF 或 fscanf 在 C 中进入无限循环
【发布时间】:2021-05-13 11:50:26
【问题描述】:

我正在尝试将几行写入文件。写完行后,当我尝试使用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);
       }

【问题讨论】:

  • 打印有用的错误消息,将它们写入标准错误,并在致命错误时退出非零。例如:const char *path = "file.txt"; fp = fopen(path,"w"); if(fp == NULL) { perror(path); exit(EXIT_FAILURE); }
  • 永远不要使用%s,其最大字段宽度最多小于要写入的缓冲区大小一倍。例如scanf("%24s",name);
  • 您已打开文件进行写入。为什么你期望fscanf 能够工作?

标签: c loops scanf


【解决方案1】:

您已打开文件进行写入(模式“w”),因此您的scanf 调用几乎肯定会失败。即使您修复了模式,也不足为奇:

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

进入无限循环。如果流中的下一个字符不是整数中的有效字符,则scanf 将返回零并且不使用它。它将反复尝试将该字符读取为整数并反复失败。这里的正确方法可能是完全停止使用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(...)) 并在输入错误时发出错误消息会更常见,但类似上述内容可能有用(取决于您的用例)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多