2017-04-18 56 views
1

在我的代码中,我从控制台输入并将其写入文件“test”,我从控制台输入输入信息,直到遇到EOF((fscanf (stdin,“%c%s%d%f”,& a,b,& c,& d))!= EOF),因为如果我们在扫描时输入EOF(ctrl + Z),fscanf会返回EOF。但是我的代码在一次EOF后并没有停止,它需要两到三个EOF来扫描终止。我手动检查第一个EOF什么也没有返回,第二个EOF返回一个和第三个EOF返回-1。扫描终止后它也打印出荒谬的东西。 我的代码如下EOF在C中不能正常工作以及打印也是荒谬的

#include<stdio.h> 
int main() 
{ 
    FILE *f; 
    char a,b[100]; 
    int c; 
    float d; 
    f=fopen("test","w"); 
    if(f==NULL) 
     printf("error"); 
    while((fscanf(stdin,"%c %s %d %f",&a,b,&c,&d))!=EOF) 
     fprintf(f,"%c%s%d%f",a,b,c,d); 
    fclose(f); 
    f=fopen("test","r"); 
    while((fscanf(f,"%c%s%d%f",&a,b,&c,&d))!=EOF) 
     printf("%c %s %d %f\n",a,b,c,d); 
    return 0; 
} 
+0

请给你确切的测试输入 – kaylum

+0

也许它与按^ Z两次模拟EOF如果你不是在一个空行的事。按^ Z作为第一个输入时,程序的行为与预期相同。 –

+1

至于为什么你必须按两次以上,是因为fscanf只有在第一次匹配转换或失败之前到达文件结尾时才返回EOF。所以你给了一些输入,然后按^ Z(2次),然后fscanf不会返回EOF。 –

回答

0

发布的代码不能正确处理换行符。第二行输入将从前一行输入的\n开始,此字符与%c转换说明符相匹配。当从键盘发送EOF时,此匹配已完成,因此fscanf()函数返回1而不是EOF。第二次发送EOF时,输入流中不再有字符,也没有匹配,并返回EOF

这也部分解释了乱码输出,因为写入文件的第二行从\n字符开始,而不是预期的字符。此外,写入该文件的fprintf()调用在字段之间不留空间,因此以后尝试读取数据失败。

此外,虽然代码检查文件是否第一次成功打开,但如果没有,则不执行任何操作。以下是带有更正的发布代码的一个版本,如果文件无法打开,则会退出并显示错误消息,如果文件未能关闭,还会打印错误消息,如果在重新打开文件之前文件未能关闭,则退出。

已将一个空格添加到fscanf()格式字符串的开头,以便跳过包括换行符在内的初始空白字符。在fprintf()格式字符串的指令之间放置了空格,最后在\n之间放置了空格,以便可以通过后续调用fscanf()来识别这些字段。请注意,如果fscanf()格式字符串中没有%s的宽度说明符,则存在缓冲区溢出的风险。但即使有了这种改进,如果输入的字符串太大,输入将会被加上额外的字符。最好使用fgets()sscanf(),更仔细地验证输入。

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

int main(void) 
{ 
    FILE *f; 
    char a, b[100]; 
    int c; 
    float d; 

    f = fopen("test", "w"); 
    if(f == NULL) { 
     fprintf(stderr, "Unable to open file for writing\n"); 
     exit(EXIT_FAILURE); 
    } 

    while((fscanf(stdin," %c%99s%d%f", &a, b, &c, &d)) != EOF) 
     fprintf(f,"%c %s %d %f\n", a, b, c, d); 

    if (fclose(f) != 0) { 
     fprintf(stderr, "Unable to close file\n"); 
     exit(EXIT_FAILURE); 
    } 

    f = fopen("test", "r"); 
    if(f == NULL) { 
     fprintf(stderr, "Unable to open file for reading\n"); 
     exit(EXIT_FAILURE); 
    } 

    while((fscanf(f," %c%99s%d%f", &a, b, &c, &d)) != EOF) 
     printf("%c %s %d %f\n", a, b, c, d); 

    if (fclose(f) != 0) { 
     fprintf(stderr, "Unable to close file\n"); 
    } 

    return 0; 
} 

这是一个示例交互。以换行符终止输入的每一行:

λ> ./a.out 
a first 3 3.14 
b second 42 2.71828 
a first 3 3.140000 
b second 42 2.718280 
+0

非常感谢您的参与你的答案。我不期待这样的答案。但是,在这个代码中,阅读不是终止在第一次EOF的遭遇。是否有可能在EOF的第一次遭遇时终止阅读。 –

+0

它终止于我的第一个'EOF'。你能否给你的问题添加一个输入例子? –

+0

对于您的解决方案中给出的相同示例输入,我必须给出两个EOF来终止扫描。但是,我正在使用代码块来编译代码。 –