IO类

IO类

IO对象不能拷贝或者被赋值
例子:

1
2
3
4
ofstream out1,out2;
out1=out2;//error!不能对流对象赋值
ofstream print(ofstream);//错误,不能初始化ofstream参数
out2=print(out2);//错误:不能拷贝流对象

因为不能拷贝流对象,所以也不能将形参或返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。读写一个IO对象会改变其状态,所以传递和返回的引用不能是const的。

条件状态(存疑)

1
2
3
4
5
strm::iostate  //一种机器相关类型,提供表达条件状态的完整功能
strm::badbit //指出流已崩溃
strm::failbit //指出一个IO操作失败了
strm::eofbit //指出流到达了文件结束
strm::goodbit //指出流未处于错误状态

一些对应函数:

1
2
3
4
s.eof();    //若eofbit置位,返回true
s.fail(); //若failbit或badbit置位,返回true
s.bad(); //若badbit置位,返回true
s.good(); //若流处于有效状态,返回true

刷新缓冲区的几种方式

1
2
3
cout<<"HI"<<endl;   //输出一个换行后刷新缓冲区
cout<<"HI"<<flush; //输出后刷新,不添加额外字符
cout<<"HI"<<ends; //输出一个空字符,然后刷新

输入输出流的关联

当一个输入流被关联到一个输出流时,任何从输入流读取数据的操作都会先刷新关联的输出流,例如:标准库将cin与cout关联在一起。

tie有2个重载的版本,一个版本不带参数,返回指向输出流的指针,如果本对象目前关联到一个输出流,那么输出的就是指向这个流的指针。若对象没关联则返回空指针。tie的第二个版本接受一个指向ostream的指针,将自己关联到此ostream(istream与ostream皆可进行关联操作)。

例如:

1
2
3
cin.tie(&cout);//cin关联到cout
ostream *old_tie=cin.tie(nullptr);//old_tie指向当前cin关联的流(如果有),同时cin不再关联其他流
cin.tie(old_tie);//重建cin与cout的关联

文件输入输出

头文件fstream中包含三个类型用来支持文件IO:ifstream从一个给定文件读取数据,ofstream向一个给定文件写入数据,fstream可以读写给定文件。

(其余待进一步理解(

string流

sstream头文件定义了三个类型来支持内存IO,这些类型可以向string写入数据,从string读取数据。istringstream从string读取数据,ostringstream向string写入数据,而头文件stringstream既可以读也可以写。

stringstream特有的操作

1
2
3
4
sstream strm;   //strm是一个未绑定的stringstream对象,sstream是头文件sstream中定义的一个类型
sstream strm(s); //strm是一个sstream对象,保存string s的一个拷贝
strm.str(); //返回strm所保存的string的拷贝
strm.str(s); //将string s拷贝到strm中,返回void

使用istringstream

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<bits/stdc++.h>
using namespace std;
struct PersonInfo{
string name;
vector<string>phone;
};
int main()
{
string line,word;
vector<PersonInfo>people;
while(getline(cin,line)){
PersonInfo info;
istringstream record(line);//似乎使用stringstream也可以
record>>info.name;
while(record>>word)
info.phone.push_back(word);
people.push_back(info);
}

return 0;
}
/*
morgan 312342234 452423424
drew 32321321 537648658
lee 8983888898 88809099 9090909909 999900909
*/

使用ostringstream

接着上面的例子,现在的例子如下:

1
2
3
4
5
6
7
8
9
10
for(const auto &a:people){
ostringstream t1,t2;//同样可以使用stringstream
t1<<a.name;
for(const auto &b:a.phone){
t1<<' '<<b;
}
if(!t1.str().empty())
cout<<t1.str()<<endl;
else cerr<<"input error!"<<a.name<<endl;
}