Fork me on GitHub

IO库

IO类

IO库类型与头文件

头文件 类型 宽字符类型 功能
iostream istream wistream 从流读数据
iostream ostream wostream 从流写入数据
iostream iostream wiostream 读写流
fstream ifstream wifstream 文件中读取数据
fstream ofstream wofstream 文件中写入数据
fstream fstream wfstream 读写文件
sstream istringstream w~ 从string读取数据
sstream ostringstream w~ 从string写入数据
sstream stringstream w~ 读写string

ifstream和istringstream都继承自istrea,所以可以像使用istream对象来使用ifstream和stringstream对象。

IO对象不能拷贝和赋值

由于不能拷贝和赋值,所以不能直接当做函数形参返回值,因为两者都有拷贝,而是用&来传参和返回。

例如:

1
2
3
4
5
6
istream &read(istream &is , Sales_data &item){  //由于IO类属于不能拷贝的类型,所以用&来传递
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is; //返回值也必须是&类型,不然相当于拷贝
}

IO库条件状态

流的条件状态位有3位,用3位表示四种状态

标志

状态 功能 值(二进制)
strm::badbit 用来指出流已崩溃 001
strm::failbit 用来指出一个IO操作失败了 100
strm::eofbit 指出流达到了文件末尾 010
strm::goodbit 指出流未处于错误状态 000

IO库定义了4个$iostate$类型的constexpr值,其实是二进制格式的,所以可以用位运算来设置标志位。即上面这四个值是固定的。

1
cout<<cin.goodbit<<' '<<cin.badbit<<' '<<cin.failbit<<' '<<cin.eofbit; //0 1 4 2

函数

函数 功能
s.eof() 如果流s的eofbit置位,则是true
s.fail() 如果流s的failbit置位,则是true
s.bad() 如果流s的badbit置位,则是true
s.good() 如果流s处于有效状态,则是true
s.clear() 将流s的所有条件状态为复位。viod类型
s.clear(flags) 给定flags状态位,将流s相应的条件状态位复位。viod类型
s.setstate(flags) 给定flags状态位,将流s相应的条件状态位置位。viod类型
s.rdstate() 返回s的条件状态,返回类型为strm::iostate

查询和管理流状态

流的状态可以用二进制来表示,比如000表示babbit、failbit、eofbit都没有置位;110表示failbit和eofbit置位。

1
2
3
4
5
6
7
cout<<cin.rdstate()<<endl;  //比如是000
cin.setstate(cin.rdstate() | cin.badbit | cin.failbit); //将cin的badbit和failbit置位

cout<<cin.rdstate(); //101 即5

cin.clear(cin.rdstate() & ~cin.badbit & ~cin.failbit); // 与操作,复位
cout<<cin.rdstate(); //恢复到000

文件输入输出

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
using namespace std;


struct PersonInfo {
string name;
vector<string> phones;
};

int main(int argc , char *argv[])
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
string line , word;
vector<PersonInfo> people;
ifstream s("C:\\Users\\lzc\\Desktop\\C++\\input.txt"); //打开文件
while(getline(s , line)){ //按行读取
cout<<line<<endl;
PersonInfo info;
istringstream record(line); //拷贝line,从string中读取数据
record >> info.name; //从record中读取
//cout<<"name:"<<info.name<<endl;
while(record >> word){
info.phones.push_back(word);
//cout<<"word::"<<word<<' '<<1;
}
//cout<<endl;
people.push_back(info);
}
s.close();
ofstream out("clustering.txt"); //默认清除当前文件内容,然后打开
//ofstream out("clustering.txt" , ofstream::app); //定位到文件末尾,就不会清除内容了
for(const auto &entry : people){
ostringstream formatted , badNums;
for(const auto &nums : entry.phones){
formatted << " " << nums; //写入formatted对象中
}
out << entry.name<<' '<<formatted.str()<<endl; //写入文件
}
}