我想在下面的代码片段中知道为什么fscanf
在执行过程中抛出-1,因此我得不到所需的输出。
#include<stdio.h>
#include<string.h>
#include<malloc.h>
int main(){
FILE *fp=NULL;
char fname[200], cmd[200];
int i=0,j=0;
system("ls /tmp/*.msg -1rt > /tmp/xyz.txt");
fp=fopen("/tmp/xyz.txt","r+");
if(fp!=NULL){
i=fscanf(fp,"%s",fname);
while(i!=EOF){
sleep(2);
printf("Filename is:'%s'\n",fname);
sprintf(cmd, "rm -rf %s; touch /tmp/a_%d_new.msg",fname,j++);
system(cmd);
memset(fname, 0, 200);
memset(cmd,0, 200);
system("ls /tmp/*.msg -rt1 > /tmp/xyz.txt");
i=fscanf(fp,"%s",fname);// fscanf will return error after some iterations
printf("The I Value is: '%d'\n",i);
}
}
if(fp!=NULL)
fclose(fp);
return 0;
}
重现步骤:
在这里,我期待从while循环中优雅地退出。在当前情况下,由于fscanf功能,它没有发生。
答案 0 :(得分:1)
在我看来,我第二次做了更好的解释,所以这是我更好的解释:
FILE
是一个包含EOF
标志和缓冲区的有状态设备。如果在缓冲时,到达文件末尾,那么它可能在缓冲区中排队,并且缓冲区不会被更新,直到它耗尽为止。本质上发生的是文件的一部分副本在内存中创建,当您对该文件进行外部更改时,内存中的副本将变得不同步。
解决方案是以某种方式同步缓冲区。如果更改文件位置,则标准库别无选择,只能更新缓存版本并重置EOF
标志。您有两种选择:
rewind
的方式使用<
,那么fgetpos
是有道理的,因为您每次循环都会覆盖文件,因此您需要从头开始阅读文件。fscanf
,后跟fsetpos
,后跟<<
只有在您打算使用<
而不是<<
时才有意义,因为{{1}连接到文件的末尾,因此当fscanf
失败时,您将能够在更新文件之后选择停止的地方。在我的第一个回答中,我还提出了一个关于你选择的设计的问题。其中的要点是,无论您做出哪种选择,fscanf
通常都不应产生EOF
值,除非您的system
调用之一无法创建文件。我想你已经根据我们下面的对话聚集了这个。不幸的是,我不能提出任何建议,除非你对你的计划应该解决的问题给出一个更广泛的概述......我只能说,while(i!=EOF)
并没有做出很多建议。感。
话虽如此,C代码调用system
是不寻常的(有点浪费,可能是错误和不安全的)...再次,我需要知道你的程序预期会出现什么问题。解决提出更好的建议。