标准IO库

 

1.istream:输入流类型,提供输入操作

ostream:输出流类型,提供输出操作。

cin:读入标准输入的istream对象,是一个istream对象

cout:写到标准输出的ostream对象,是一个ostream对象

cerr:输出标准错误的ostream对象

>>:从istream对象中读入输入

<<:把输出写到ostream对象中

getline(istream&,string&)从istream对象读取一个单词,然后string对象中

 

2.IO标准库类型和头文件

iostream:定义读写控制窗口的类型

fstream:定义读写已命名文件的类型

sstream:定义用于读写存储在内存中的string对象 istringstream:从string对象中读取,ostringstream:写到string对象中,stringstream对string对象进行读写

 

3.标准库类型不允许做复制或者赋值操作,因此IO对象不可赋值和复制。

以下是错误的:

ofstream out1,out2;

out1=out2;

ofstream print(ofstream);

out2=print(out2);//这个out2作为参数时,调用了ofstream拷贝复制

这也说明:

1).因为stream不支持复制,而只有支持复制的元素才能存储在vector或其他容器类型里。由于流对象不能复制,故不行。

2).形参或者返回类型都会调用拷贝构造函数生成临时对象什么的,所以形参和返回类型都不能是流类型。如果需要传递或者返回IO对象,则必须传递或者返回指向该对象的指针或引用

下面的就是正确的:

ofstream &print(ofstream&);

while(print (out2));

 

4.所有的流对象都包括一个类型为iostate的条件状态成员,该成员由setstate和clear操作管理。该状态成员以二进制位bit的形式使用。

strm::iostate 机器相关的整型,由各个iostream类定义,用于定义条件状态

strm::badbit 系统级的鼓掌,如无法恢复的读写错误。出现此错误,则该流通常就不能使用了。

strm::failbit 出现可以恢复的错误,如希望输入数值类型,结果输入了字符,此时设置failbit标志。

strm::eofbit 遇到文件结束符时设置的,此时还设置了failbit。

流的状态由bad,fail,eof和good操作揭示。如果bad,fail,eof中任意一个为true,则检查流本身将显示该流处于错误状态。

s.eof()  设置了流s的eofbit值,则该函数返回true

s.fail()  设置了s的failbit值,则返回true

s.bad() 设置了s的badbit值,则返回true

 

s.good() 如果流s处于有效状态,返回true

 

s.clear()将s中所有的状态值设置为有效状态

s.clear(flag)将s中某个指定的条件设置为有效,flag类型为strm::iostate

s.setstate(flag) 给流s添加指定条件。flag类型为strm::iostate

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

 

 1 int ival;
 2 while(cin>>ival,!cin.eof()){
 3 
 4 if(cin.bad())
 5 throw runtime_error("IO stream corrupted");
 6 if(cin.fail()){
 7 cerr<<"bad data,try again";
 8 cin.clear(istream::goodbit);
 9 cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
10 continue;
11 }
12 
13 }

 

条件状态的访问

istream::iostate old_state=cin.rdstate();

cin.clear();

process_input();

cin.clear(old_state);

 

5.每个IO对象管理一个缓冲区,用于存储程序读写的数据。eg:系统将输入存储在与流关联的缓冲区中,以下情况会导致缓冲区的内容被刷新,即写入到真实的输出设备或者文件

1)程序正常结束。作为main返回工作的一部分,将清空所有输出缓冲区。

2)在一些不确定的时候,缓冲区满了,在写入下一个值前刷新。

3)用操作符显示的刷新缓冲区,例如endl,flush,ends。endl加入一行(就是所谓的换行),然后刷新缓冲。flush刷新前已不做别的,ends刷新前加个null(显示出来就是个空格) 。所以以后多用endl,少用‘\n’,防止程序崩溃时,输出是否还残留在缓冲区,未输出到设备中。

4)在每次输出操作执行完成之后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区。

5)将输出流与输入流关联起来,在读输入流时将刷新其关联的输出缓冲区。标准库将cin和cout是绑在一起的,因此cin会导致cout关联的缓冲区也被刷新。

一个ostream每次只能与一个istream对象绑再一起。如果调用tie函数时传递参数0,就是解绑该流绑的流。

tie函数,可以由istream或者ostream对象调用,使用一个指向ostream对象的指针形参。

cin.tie(&cout);

ostream *old_tie=cin.tie();//得到cout

cin.tie(0);

cin.tie(&cerr);

cint.tie(0);

cin.tie(old_tie);

 

6.fstream头文件定义了三种支持文件IO的类型:

ifstream,由istream派生而来,提供读文件功能。

ofstream,由ostream派生而来,提供写文件功能

fstream,由iostream派生而来,提供读写同一个文件的功能。

fstream除了继承下来的行为外,还定义了两个自己的新操纵----openclose,以及一个形参是要打开的文件的文件名的构造函数

1)为ifstream或者ofstream对象提供文件名作为初始化式,就相当于打开了特定的文件

ifstream infile(ifile.c_str());//由于历史原因,IO标准库使用c风格字符串而不是c++ string风格的字符串作为文件名。使用string对象的c_str()即可。

ofstream outfile(ifile.c_str());

2)定义fstream流对象,使用前得捆绑具体的文件

ifstream infile;

ofstream outfile;

infile.open("in");

outfile.open("out");

3)检查文件是否打开成功,直接if(文件名)或者if(!infile),这就是打开是否失败了~

4)将文件流重新与新文件绑定得先close

ifstream infile("in");

infile.close();

infile.open("next");

5)清除文件流的状态

eg.一个vector对象,包含一些要打开和读取的文件的名字,程序要对每个文件中存储的单词做一些处理假设vector对象命名为files

a.这个input是临时对象,每次对于一个心的it->c_str()文件都要创建心的流对象

int main(){  

vector<string> v;

 v.push_back("1.txt");

 v.push_back("2.txt");

 vector<string>::iterator it=v.begin();

 while(it!=v.end()){  

 fstream input(it->c_str());

 if(!input){  

 cout<<"open file failed !"<<endl;

  break;

 }  

 string s;

 while(input>>s){

      cout<<input.rdstate()<<ends; //全是0

    cout<<input.good()<<ends;  //全是1

    cout<<s<<ends;

 }  

 ++it;

 }

 return 0;
}

b .将ifstream放到while外面,可以防止不停的新建流。另外关闭流并不能改变流对象的内部状态,如果最后的读写失败了,对象的状态将保持为错误模式,值到执行clear操作重新恢复留的状态为止。调用clear后,就像重新创建了该对象一样。

 1 ifstream input;
 2 vector<string>::const_iterator it=files.begin();
 3 while(it!=files.end()){
 4 input.open(it->c_str());
 5 if(!input)
 6 break;
 7 while(input>>s)
 8 process;
 9 input.close();
10 input.clear();
11 ++it;
12 }

 

7.文件模式,模式是文件的属性,而不是流的属性

in:打开文件做读操作

out:打开文件做写操作,但是ofstream默认out模式打开文件时,文件会被清空,丢弃掉文件存储的所有数据,相当于同时指定了out和trunc模式,如果不想打开时候清除就用ofstream                 outfile("file1",ofstream:out|ofsteam::app)

app:每次写之前找到文件尾(append)

ate:打开文件后立即将文件定位到尾部。(atend),只在打开时侯有效,即只会改变文件打开时的初始定位,在第一次读或写之前,将文件定位到文件末尾处。

trunc:打开文件时候清空已存在的文件流

binary:以二进制的模式进行IO操作。以字节序列的形式处理,而不解释流中的字符。

 

8.字符串流标准库

 istringstream:由istream派生二来,提供读string的功能

ostringstream:由ostream派生而来,提供写string的功能

stringstream:由iostream派生而来,提供读写string的功能

必须包含sstream头文件

除了继承自iostream类型派生而来所有操作,还各自定义了一个有string形参的构造函数和一个名为str的成员函数

stringstream strm;// 创建自由的stringstream对象

stringstream strm(s);//创建存储s的副本的stringstream对象,其中s是string类型的对象

strm.str();//返回strm中存储string类型对象

strm.str(s);//将string类型的s复制给strm,返回void

string line,word;
while(getline(cin,line)){
   istringstream strm(line);
   while(strm>>word){//获取每行中的单词
    process(word);
}


}

 

 

 

 

 

 

 

 

 

posted @ 2012-07-06 16:32  FollylloF  阅读(459)  评论(0编辑  收藏  举报