C++Primer 5th Chap8 The IO Library

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完整的实现流程

posted @ 2019-09-13 14:02  Dragonsburg  阅读(167)  评论(0编辑  收藏  举报