标准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除了继承下来的行为外,还定义了两个自己的新操纵----open和close,以及一个形参是要打开的文件的文件名的构造函数。
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); } }