加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

fscanf把最后一行读两遍的问题

(2011-11-09 14:23:42)
写一个文件1.txt,内容是:
v 1
v 2
v 3
(最后没有空行)

使用如下代码:

#include <iostream>
using namespace std;

int main(int argc, char** argv) {
    FILE* pFile = NULL;
    char str[50];
    int num;
    pFile = fopen("1.txt", "rt");
    if(pFile==NULL) { cerr<<"error!"<<endl; exit(-1); }
    while(!feof(pFile)) {
        fscanf(pFile, "%s", str);
        if(strcmp(str,"v")==0) {
            fscanf(pFile, "%d", &num);
            printf("%d\n", num);
        }

    }
    fclose(pFile);

    return 0;
}


最后输出结果正确,为“1 \n 2 \n 3”。
但是如果在1.txt的“3”行后面加入一个空行(直接在“3”行末尾回车),
最后的输出结果就变成了“1 \n 2 \n 3 \n 3”。
(实际上,不论加入多少个空行,都只会把最后一行读2遍。

分析原因是:当我们用while(!feof(pFile)){...}判断文件是否结束,并处理文件内容的时候经常会遇到文件最后一行重复两遍的问题,这是因为feof在遇到文件结束符EOF这个位置时,返回的还是0;而到下一个位置时才返回1,这时while循环才退出。所以单纯用上面的while循环判断会出现重复的现象。

注意,fscanf函数在遇到文件EOF时会返回-1;因此可以将程序的原fscanf行改成:
        int res = fscanf(pFile, "%s", str);
        if(res == -1) { break; }
最后一行读2遍地问题得到解决。最后的代码是:

#include <iostream>
using namespace std;

int main(int argc, char** argv) {
    FILE* pFile = NULL;
    char str[50];
    int num;
    pFile = fopen("1.txt", "rt");
    if(pFile==NULL) { cerr<<"error!"<<endl; exit(-1); }
    while(!feof(pFile)) {
        int res = fscanf(pFile, "%s", str);
        if(res == -1) { break; }
        if(strcmp(str,"v")==0) {
            fscanf(pFile, "%d", &num);
            printf("%d\n", num);
        }

    }
    fclose(pFile);

    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有