之前我们已经接触到一些IO的操作了,比如istream,提供输入操作,对应 cin»;ostream提供输出操作,对应cout«,接下来简单了解一下IO类。
8.1 IO类
头文件 | 类型 |
---|---|
iostream | istream,wistram从流读入数据 ostream,wstream从流写入数据 iostream,读写流 |
fstream | ifstream,wifstream从流读入数据 ofstream,wofstream从流写入数据 fstream,读写流 |
sstream | istringstream,wistringstream从string读入数据 ostringstream,wostringstream从string写入数据 stringstream,wstringstream读写string |
这里有个小tips,>>理解成输入流,无论是文件输入还是控制台输入,<<理解成输出流,不管是输出到文件,还是控制台
8.1.1IO对象无拷贝或者赋值
ofstream out1;
ostream&os=cout;//正确,引用传递
ofstream out2(out1);//错误的,无拷贝
out1=out2;//错误,无赋值
8.1.2管理输出缓冲
输出流一般都具有缓冲区,比如执行下面的代码
os<<"please enter a value";
文本串可能立刻打印出来,也可能先保存在缓冲区,随后打印。这一点就允许操作系统合并程序的多个输出成为一个单一的写操作,从人人提升性能。刷新缓冲区的方式有以下几种
- 程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行
- 缓冲区满
- 使用endl(刷新并且换行),flush(只刷新,不附加任何额外字符),ends(输出空白字符,并且刷新)等操纵符显示刷新
- 在输出操作之后,添加unitbuf设置状态,清空缓冲区。默认情况下cerr是unitbuf的,因此写到cerr的内容都是理科刷新的
- 一个输出流可能会关联到另一个流。这种情况下,当读写被关联到的流的时候,关联到的流的缓冲区立刻刷新。默认情况下cin和cerr都关联cout。
cout<<unitbuf;//所有输出操作后会被刷新到缓冲区
cout<<nounitbuf;//回到正常的缓冲模式
cin>>ival;//cout会被刷新
//使用tie来关联两个不相关的流
cin.tie(&cout); //绑定
ofstream*old_tie=cin.tie(nullptr);//相当于完成两个操作,第一个old_tie指向之前的绑定关系 第二个解绑,理解i++
cin.tie(&cerr);
cin.tie(old_tie);
8.2头文件输入输出
头文件fstream定义了三种类型对文件进行操作,ifstream读取文件的数据,ofstream向文件写入数据,fstream读写文件。
8.2.1使用文件流对象
这个比较简单,就相当于使用上面的函数
ifstream input(ifilename);//读取的文件的名字
ofstream output(ofilename);//输出的文件的名字
if(input);//查看是否绑定成功
input.close();//解绑
8.2.2文件模式
文件模式也就是mode,一般来说,mode有下面这几种
in | 以读方式打开 |
---|---|
out | 以写方式打开 |
app | 每次写操作均定位到文件末尾 |
ate | 打开文件后立刻定位到末尾 |
trunc | 截断文件(我的理解是清空文件) |
binary | 以2进制的方式进行IO |
我感觉用的比较多的就是app模式,因为追加写不会清空文件中原有的数据。
8.3string流
与前者相似,头文件sstream定义了三种类型对文件进行操作,istringstream读取string的数据,ostringstream向string写入数据,stringstream读写string类型。
8.3.1使用istringstream
int main(){
string line,word;
vector<Person>people;//假设有这个类,包含name和phono
while(getline(cin,line)){//输入line “dsy” “152 **** ****‘
Person p;
istringstream record(line);//将line拷贝给流
record>>p.name>>p.phono;
people.push_back(p);
}
}
8.3.2使用ostringstream
这个的话主要就是将string类型按照想要的格式存储起来,之后一并输出,这个就不赘述了。感觉目前用到的几率不高。