IO类:
头文件 | 类型 |
iostream | istream,从流读取数据 |
ostream,向流写入数据 | |
iostream,读写流 | |
fstream | ifstream,从文件读取数据,默认in模式打开 |
ofstream,向文件写入数据,默认out模式打开 | |
fstream,读写文件,默认in和out模式打开 | |
sstream | istringstream,从string读取数据 |
ostringstream,向string写入数据 | |
stringstream,读写string |
宽字符(wchar_t)版本的类型和函数在名称开头多一个w
普通流、文件流、string流和宽字符流版本的使用方法一致
IO对象无拷贝和赋值,进行IO操作的函数通常以引用方式传递和返回流,而且引用不能是const的
IO库条件状态表
strm::iostate | strm是一种IO类型(见上表),iostate是反映条件状态完整功能的一种类型(包含下面4个constexpr值) |
strm::badbit | 流已崩溃 |
strm::failbit | IO操作失败 |
strm::eofbit | 流到达文件结束 |
strm::goodbit | 流未处于错误状态,值为0 |
s.eof() | 流s的eofbit置位,返回true |
s.fail() | 流s的failbit或badbit置位,返回true |
s.bad() | 流s的badbit置位,返回true |
s.good() | 流s处于有效状态,返回true |
s.clear() | 流s中的所有条件状态位复位,设置流的状态为有效,返回void |
s.clear(flags) | flags类型为strm::iostate,根据flags标志位将流s的对应条件状态位复位 |
s.setstate(flags) | flags类型为strm::iostate,根据flags标志位将流s的对应条件状态位复位 |
s.rdstate() | 返回流s的当前条件状态,返回类型strm::iostate |
确定一个流对象的状态的最简单方法是将它作为一个条件使用:
while(cin>>word){/*.....*/}
管理条件状态:
一旦badbit被置位,流就无法再使用;
如果failbit被置位,说明流发生了可恢复的错误;
到达文件结尾,failbit和eofbit都被置位;
if( cin >> s )等价于if ( ! s.fail ( ) )
使用方法如下:
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int main(){ 5 string str; 6 auto old_state=cin.rdstate();//获取原有状态 7 cin.clear();//cin有效化 8 getline(cin,str); 9 cin.setstate(old_state);//置cin为原有状态 10 cin.clear(cin.rdstate()&~cin.failbit&~cin.badbit);//在保持其他位不变时,复位failbit和badbit 11 }
刷新输出缓冲区:
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 cout<<"Sieg"<<endl;//输出换行,然后刷新缓冲区 5 cout<<"Heil"<<flush;//刷新缓冲区并且不附加任何字符 6 cout<<"!"<<ends;//输出空字符,然后刷新缓冲区 7 cout<<unitbuf;//其后所有输出操作后都刷新缓冲区 8 cout<<nounitbuf;// 其后所有输出操作后都进行正常缓冲模式(用于终止unitbuf) 9 }
关联输入和输出流:
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 //x.tie(&os);关联x到输出流os 5 cin.tie(&cout);//关联流cin到输出流cout 6 ostream *old_tie=cin.tie(nullptr);//cin不与其他流关联 7 cin.tie(&cerr);//关联流cin到输出流cerr(仅作为例子,不建议这样做) 8 cin.tie(old_tie);//cin不与其他流关联(正常情况下的cin与cout的关系) 9 }
每个流只能关联到一个流,而多个流可以关联到同一输出流
文件输入输出:
fstream fstrm; | 建立一个未绑定的文件流,名为fstrm, |
fstream fstrm(s); | 建立一个绑定文件(名为s,s是string或者c风格字符指针)文件流,默认文件模式 |
fstream fstrm(s,mode); | 建立一个绑定文件的文件流,文件模式指定为mode |
fstrm.open(s); | 打开文件s,并使文件与流fstrm绑定,返回void |
fstrm.close(); | 关闭与流绑定的文件,返回void |
fstrm.is_open(); | 指出与流关联的文件是否成功打开且未关闭,返回bool |
具体使用:
1 #include<iostream> 2 #include<fstream> 3 #include<cstring> 4 using namespace std; 5 int main(int argc,char *argv[]){ 6 string ifile="iofile.txt"; 7 ifstream in(ifile);//ifstream打开指定文件 8 ofstream out;//输出文件流不关联任何文件 9 out.open(ifile+".copy");//打开指定文件 10 if(out){//检查打开成功与否 11 cout<<ifile; 12 in.close();//关闭文件 13 in.open(ifile+"2"); //打开另一文件 14 } 15 }
文件模式:
in | 以读方式打开,仅限fstream对象和ifstream对象 |
out | 以写方式打开,仅限fstream对象和ofstream对象,自动截断文件(即使没设定trunc)(为防止截断文件,需要同时设定为in或app) |
app | 每次写操作前都定位到文件末尾,自带out模式,仅限未设定trunc时才能使用 |
ate | 打开文件后立即定位到文件末尾 |
trunc | 截断文件,仅限out也被设定时才能使用 |
binary | 以二进制方式进行IO |
1 //指定模式打开文件 2 ofstream out1("File1");// 3 ofstream out2("File2",ofstream::out); 4 ofstream out3("File3",ofstream::out|ofstream::app);
string流:
sstream strm; | strm是一个未绑定的stringstream对象 |
sstream strm(s); | strm保存string s 的一个拷贝(构造函数explicit) |
strm.str(); | 返回strm保存的拷贝 |
strm.str(s); | 将string s 拷贝到strm,返回void |
1 #include<iostream> 2 #include<sstream> 3 #include<vector> 4 #include<string> 5 using namespace std; 6 struct PersonInfo{ 7 string name; 8 vector<string> phones; 9 }; 10 int main(int argc,char*argv[]){ 11 string line,word; 12 vector<PersonInfo> people; 13 while(getline(cin,line)){ 14 PersonInfo info; 15 istringstream record(line); 16 record>>info.name; 17 while(record>>word){ 18 info.phones.push_back(word); 19 } 20 people.push_back(info); 21 } 22 for(const auto &entry:people){ 23 ostringstream formatted,badNums; 24 for(const auto &nums:entry.phones){ 25 if(!valid(nums)){ 26 badNums<<" "<<nums; 27 } 28 else{ 29 formatted<<" "<<format(nums); 30 } 31 } 32 if(badNums.str().empty()){ 33 cout<<entry.name<<" " 34 <<formatted.str()<<endl; 35 } 36 else{ 37 cerr<<"Input error: "<<entry.name 38 <<" invalid number(s) "<<badNums.str()<<endl; 39 } 40 } 41 }
上述代码为sstream完整的实现流程