fstream 中 eofbit 的控制

来源:互联网 发布:网络歌曲么么哒 编辑:程序博客网 时间:2024/06/10 07:09

    读取文件到达末尾时,eofbit 置1。可以用 fstream file; file.clear()清除eofbit,再file.seekg(0) //seekg第二个参数默认是ios::beg。这样就可以重新读取文件。

但如果用file.clear(ios::filebit)或file.clear(ios::badbit),虽然清除了eofbit的位,但由于failbit或badbit置位了,就不能读取数据。所以必须用clear()或clear(ios::goodbit) // 默认参数是ios::goodbit。


请参考:http://www.cplusplus.com/reference/ios/basic_ios/clear/


扩展:

1. 以下参考资料来自:http://blog.csdn.net/jiangxinyu/article/details/7758465

2. 标准IO库定义的------条件状态

标准IO 库管理一系列条件状态(condition state)成员,用来标记给定的 IO 对象是否处于可用状态,或者碰到了哪种特定的错误。如下列出了标准库定义的一组函数和标记,提供访问和操纵流状态的手段。

strm::iostate               这是机器相关的整型别名,代表一种类型,由各个io类定义,用于定义条件状态(strm在这里代表各个流类型)。

strm::badbit                strm::iostate类型的值,用于指出被破坏的流。

strm::failbit                 strm::iostate类型的值,用于指出失败的 IO 操作。

strm::eofbit                 strm::iostate类型的值,用于指出流已经到达文件结束符。

s.eof()                        返回eof标志位的值,真或假。

s.fail()                        返回fail标志位的值,真或假。

s.bad()                      返回bad标志位的值,真或假。

s.good()                    检测流s的有效性,当eof,fail,bad都不为真时good标志位有效,调用good()函数返回真值。

s.clear()                    将流s中的所有状态值都重设为有效状态。

s.clear(flag)               将流s中的某个指定条件状态置为有效,flag是strm::iostate类型的条件状态,若括号内不写具体条件状态则将所有条件状态全部设置有效。

s.setstate(flag)          给流添加指定条件,设置flag位为触发状态,flag是strm::iostate类型对象。

s.rdstate()                 返回流s的当前条件,返回值类型为strm::iostate。

总结-----条件状态

  • 所有流对象都包含一个条件状态成员,他是strm::iostate类型的对象,以二进制位的形式使用。
  • failbit, eofbit, badbit和goodbit是四个strm::iostate类型的常量值,他们本身分别表示一种条件状态,具体如下表:
常量含义fail标志位oef标志位bad标志位ios::badbit已达到文件结束001ios::eofbit输入(输出)流出现非致命错误,可挽回010ios::failbit输入(输出)流出现致命错误,不可挽回100ios::goodbit流状态完全正常000
  • badbit, eofbit, failbit,goodbit构成了四个基本流状态
  • 用cout检测goodbit, badbit, eofbit, failbit的值分别是0,1,2,4,这与上面的表格不是正好完全对应着吗,呵呵(goodbit:0000 0000;  badbit:0000 0001;eofbit:0000 0010; failbit:0000 0100)。
  • 可使用clear和setstate来操作和管理条件状态成员,他们常与badbit,eofbit,failbit,goodbit以及位或“|”结合起来使用。
  • 用bad(), fail(), eof()和good()操作可以检测流状态是否属于,还可以用rdstate()来返回整个条件状态成员。

2.1 rdstate的使用:

rdstate成员函数返回一个iostate类型的值,前面已经说过,这是一个与机器相关的整型,该值对应于流的整个条件状态。如下代码:(摘自cplusplus.com)

// getting state of stream object

#include <iostream>

#include <fstream>

using namespace std;

int main ()

ifstream is; 

is.open ("test.txt");

if ( (is.rdstate() & ifstream::failbit ) != 0 ) //检测fail标志位是否被设置,即是否遇到错误  

cerr << "Error opening 'test.txt'\n"; return 0;

}

2.2 clear的使用:

clear用于设置标志位而不是清除标志位,即按照实参设置流状态,强制覆盖原有状态,其工作方式有两种:

  • 带有failbit, eofbit, badbit,goodbit中的一个或多个作为参数,按照具体实参设置流对象,例如goodbit作实参时就设置流状态各位为0。
  • 不带参数,即默认状态,效果如同带goodbit作为参数,会将所有标志位设置为有效。
// clearing errors#include <iostream>#include <fstream>using namespace std;int main () {  char buffer [80];  fstream myfile;  myfile.open ("test.txt",fstream::in);  myfile << "test";  if (myfile.fail())  {    cout << "Error writing to test.txt\n";    myfile.clear();  }  myfile.getline (buffer,80);  cout << buffer << " successfully read from file.\n";  return 0;}

2.3 setstate的使用:

setstate用于设置标志位状态,与clear的区别在于它只是在原有状态的基础上以叠加的方式更新实参对应状态标志,而不会强制覆盖原有状态,使用方式:

  • 传递一个strm::iosatate类型的参数(可以是单个的,也可以是用“位或”连接的多个iostate对象)


2. 以下参考资料来自:http://blog.csdn.net/leonardwang/article/details/4881122


C++ stringstream

stringstream

clear()是清除failbit位和/或eofbit位(还有badbit位)的。当使用操作符<<时,failbit位和eofbit位是没有设置的,所以,在不用clear的情况下可以继续执行<<操作,加入新值。

但是当使用>>操作符时且有可能改变stringstream的状态时(比如出错,行到底)就要使用clear()才能继续给stringstream读入新值,这是因为>>操作从stringstream中读出数据流时,stringstream会设置failbit和eofbit位,而在没有清这些位之前是读不进去数据的。

由于stringstream构造、解析函数很耗时,所以尽量只创建一个。

eg:

int main()
{
 stringstream ss;
 string s[2]={"34 43","11 55"};
 int temp;
 for (int i=0;i<2;i++)
 {
  ss << s[i];
  while (!ss.eof())    //到底了
  {
   ss >> temp;
   cout << temp << endl;

                                           //由于到此,状态位未改变,所以不可clear(),否则ss.eof()的循环永远无法跳出
  }
  ss.clear();  //为了下个循环继续能读入,所以清除下标记位(eof),否则无法读入ss
 }
 return 0;
}


3.http://bbs.csdn.net/topics/360108849

0 0
原创粉丝点击