Chinaunix首页 | 论坛 | 博客
  • 博客访问: 483515
  • 博文数量: 23
  • 博客积分: 398
  • 博客等级: 一等列兵
  • 技术积分: 850
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 22:18
文章分类

全部博文(23)

文章存档

2013年(9)

2012年(14)

分类: C/C++

2013-06-06 21:08:48

对于文本文件,当我们使用eof()判断文件是否结束时会多读一次(c语言也有类似的情况),或许你有遇到过这种情况。

先看下面的例子吧:

点击(此处)折叠或打开

  1. #include<iostream>
  2. #include <string>
  3. #include<fstream>
  4. #include<cstdlib>
  5. using namespace std;

  6. int main()
  7. {
  8.     char data;
  9.     ifstream infile;

  10.     infile.open("in.txt");

  11.     if(infile.fail())
  12.     {
  13.         cout<<"Fail to open the input file"<<endl;
  14.         exit(1);
  15.     }

  16.     while( !infile.eof() )
  17.     {
  18.         infile >> data;
  19.         cout << data ;
  20.     }

  21.     infile.close();
  22.     cout << endl;

  23.     return 0;
  24. }


假设输入文件in.txt的内容为:

abc

则输出结果是:abcc

明明使用了eof()判断了,为什么还是这样的呢?原因是这样的,因为eof()发现读到文件结束标志EOF(-1)时并不会立刻返回true

而是比较后知后觉。此时需要再读一下,这时eofbit才被设置(并且设置其他的bit,如goodbit),等下次调用eof()返回true C++ Standard LibraryConstants  for  the  Stateof  Streams有一个表如下:


既然知道问题所在,问题就好解决了。

方法一:

while( !infile.eof() )

{

infile >> data;

if( infile.good() 

{

cout << data ;

}

}

或者:

while( !infile.eof() )

{

infile >> data;

if (infile.fail())

                {

                        break;

                }

cout << data ;

}

方法二:

while(infile >> data)

{

        cout << data ;

}

方法三:使用peek函数

while(infile.peek()!=EOF)

{

        infile >> data; //>>读取时会忽略(跳过)空格等空字符,使用infile.get(data)不会

        cout << data ;

}

peek()只是查看缓冲的下一个元素,并不读取(即文件内部指针不会向后移动)c++ Standard Library有一句描述:

 Returns the next character to be read from the  stream without extracting it.

可以看出peek有一个局限,只能在读取char类型时使用。

例如,in.txt内容为以空格隔开的字符串,因为我们在程序中写入文件时,每写入一个字符串之后跟一个空格,所以最后一个字符串之后有空格:

string str;

while(infile.peek()!=EOF)

{

        infile >> str;

        cout << str << endl;

}

同样会多读一次, 不信可以试试看,呵呵。至于如何解决,我想你应该能够举一反三了吧。



阅读(18748) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~