2015-03-19 67 views
3

最近我正在阅读Deitel编写的C How to Program,第7版的文件处理部分。对于写入文件,它使用这个例子:C程序打印最后一行两次(文件I/O)

// Fig. 11.2: fig11_02.c 
// Creating a sequential file 
#include <stdio.h> 

int main(void) 
{ 
    unsigned int account; // account number 
    char name[ 30 ]; // account name 
    double balance; // account balance 

    FILE *cfPtr; // cfPtr = clients.dat file pointer 

    // fopen opens file. Exit program if unable to create file 
    if ((cfPtr = fopen("clients.dat", "w")) == NULL) { 
     puts("File could not be opened"); 
    } // end if 
    else { 
     puts("Enter the account, name, and balance."); 
     puts("Enter EOF to end input."); 
     printf("%s", "? "); 
     scanf("%d%29s%lf", &account, name, &balance); 

     // write account, name and balance into file with fprintf 
     while (!feof(stdin)) { 
     fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
     printf("%s", "? "); 
     scanf("%d%29s%lf", &account, name, &balance); 
     } // end while 

     fclose(cfPtr); // fclose closes file 
    } // end else 
} // end main 

,你可以看到,它会扫描并打印数据先在别的块,然后在while循环。因为我认为做两遍没有意义,它只是删除了if-else部分并编译它。以及它工作正常,但后来我意识到它重复输出文件中的最后一行输入。在Deitel版本中没有。

我的版本有什么问题?为什么它复制最后一行?我认为这可能是一个循环条件的问题,但我不知道..

编辑:此代码是由Dietel使用,我不相信这是错误的,因为他正在使用if-else来修复引起的问题通过!feof。但我想知道如何解决它,而没有,如果 - 其他。

在编辑的版本

没有的if-else,只带环的输入和输出是:

输入:

1 test 25.6 
2 some 95 

输出:

1 test 25.6 
2 some 95 
2 some 95 
+0

可能重复(http://stackoverflow.com/questions/5431941/while-feof-文件是总是错误的) – 2015-03-19 11:26:53

+1

我读过,但我认为我的情况是不同的。 – vvvsg 2015-03-19 11:29:12

+0

在完成'main'函数之前,您应该输入'return 0;'或某个数字。 – Gophyr 2015-03-19 11:38:58

回答

4

重点是E OF测试必须始终遵循scanf(),并在打印读取信息之前进行。

if-else条件仅用于处理最终打开的错误条件,所以如何修改代码并不完全清楚。然而人们常常试图做的事:

while (!feof(stdin)) { 
    scanf("%d%29s%lf", &account, name, &balance); 
    fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
    printf("%s", "? "); 
    } 

,这是错误的,因为读的是最后的数据时,它不会“读EOF”(EOF是你读完数据你后遇到条件):只随后的scanf()将会执行,并且输出函数将会输出错误的数据(以前的数据,由于输入错误而未被覆盖,这就是最后一行重复的原因)。

例如,这是正确的:

for (;;) { 
    scanf("%d%29s%lf", &account, name, &balance); 
    if (feof(stdin)) break; 
    fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
    printf("%s", "? "); 
    } 

而实际上我更喜欢重复相同scanf()线两次被Deitel公司的建议。

1

更改为:

else { 
    puts("Enter the account, name, and balance."); 
    puts("Enter to end input."); 

    // write account, name and balance into file with fprintf 
    while (scanf("%d%29s%lf", &account, name, &balance)==3) 
    { 
    fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
    printf("%s", "? "); 
    } 
    fclose(cfPtr); // fclose closes file 
} // end else 
+0

3是参数的数量正确吗? – vvvsg 2015-03-19 11:40:32

+0

阅读文档(习惯于查找 - 它有帮助)。 – 2015-03-19 11:55:46

0

改正的代码是:

while (!feof(stdin)) { 
    if(!feof(stdin)) 
    { 
     fprintf(cfPtr, "%d %s %.2f\n", account, name, balance); 
     printf("%s", "? "); 
     scanf("%d%29s%lf", &account, name, &balance); 
    } 
} 
的[ “而(!FEOF(文件))” 永远是错]