C++ Primer学习笔记-----第八章:IO类

C++语言不直接处理输入输出,而是通过一族定义在标准库中的类型来处理IO。
这些类型支持从设备读取数据、向设备写入数据的IO操作,设备可以是文件、控制台窗口等
还有一些允许内存IO,即从string读取数据,向string写入数据。

在这里插入图片描述
1.IO类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
查询流的状态:
在这里插入图片描述
在这里插入图片描述
管理条件状态:

流对象的rdstate成员返回一个iostate值,对应流的当前状态。setstate操作将给定条件位置位,表示发生了对应错误。
clear成员是一个重载的成员:一个不接受参数,一个接受一个iostate类型的参数。
clear不接受参数的版本清楚(复位)所有错误标志位。执行clear()后,调用good会返回true.
举例使用这些成员:
auto old_state = cin.rdstate();		//记住cin的当前状态
cin.clear();						//使cin有效
process_input(cin);					//使用cin
cin.setstate(old_state);			//将cin置为原有状态
带参数的clear版本接受一个iostate值,表示流的新状态。为了复位单一条件状态位,我们首先用rdstate读出当前条件
状态,然后用位操作将所需位复位来生成新的状态。例如:下面代码复位failbit和badbit,eofbit不变。
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);

管理输出缓冲:

导致缓冲刷新的原因:
1.程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行。
2.缓冲区满时,需要刷新缓冲,而后新的数据才能写入缓冲区。
3.在每个输出操作之后,我们可以用操作符unitbuf设置流的内部状态,来清空缓冲区。默认情况下,对cerr是设置unitbuf的,
  因此写到cerr的内容都是立即刷新的。
4.一个输出流可能被关联到另一个流。在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。例如,默认情况下
  cin和cerr都关联到cout。因此读cin或写cerr都会导致cout的缓冲区被刷新。

刷新缓冲区:

cout<<"hi"<<endl;		//endl:完成换行并刷新缓冲区
cout<<"hi"<<flush;		//flush:只是刷新缓冲区
cout<<"hi"<<ends;		//ends:输出一个空字符,然后刷新缓冲区

cout<<unitbuf;			//之后的所有输出操作都会立即刷新缓冲区
//任何输出都立即刷新,无缓冲
cout<<nounitbuf;		//回到正常的缓冲方式
注意:如果程序崩溃,输出缓冲区不会被刷新。
要确认那些你认为已经输出的数据确实已经刷新了。

关联输入和输出流:

tie无参版本,返回指向输出流的指针。如果本对象当前关联到一个输出流,则返回的就是指向这个流的指针,如果对象
未关联到流,则返回空指针。
tie第二个版本接受一个指向ostream的指针,将自己关联到此ostream。即,x.tie(&o)将x关联到输出流o。
举例:可以将istream或ostream对象关联到ostream。
cin.tie(&cout)		//仅仅用来展示:标准库将cin和cout关联在一起
ostream* old_tie = cin.tie(nullptr);	//cin不再与其他流关联
cin.tie(&cerr);							//读取cin会刷新cerr
cin.tie(old_tie);						//重建cin和cout间的正常关联

2.文件输入输出

文件操作类型:
ifstream:读文件
ofstream:写文件
fstream:读写文件,继承自iostream

在这里插入图片描述
使用文件流对象

举例:
1.读取整个文件
string path = "C:\\Users\\Administrator\\Desktop\\abc1.txt";
string content;
ifstream ifs(path);
ifs>> content;
ifs.close();

2.读取文件的每一行
string path2 = "C:\\Users\\Administrator\\Desktop\\abc2.txt";
string line;
ifstream ifs;
ifs.open(path2);
while(getline(ifs,line))
{cout<<line<<endl;}
ifs.close();

如果open失败,failbit会被置位,因为调用open可能失败,进行open是否成功的检测通常是一个好习惯。
ofstream out;
out.open(path);
if(out)			//检测open是否成功
对一个已经打开的文件流调用open会失败,并会导致failbit被置位。
为了将文件流关联到另外一个文件,必须首先关闭已经关联的文件。
如果open成功,则open会设置流的状态,使得good()true。

当一个fstream对象离开其作用域时,与之关联的文件会自动关闭。
当一个fstream对象被销毁时,close会自动被调用。

*****文件模式*****
in:		以读方式打开
out:	以写方式打开
app:	每次写操作前均定位到文件末尾
ate:	打开文件后立即定位到文件末尾
trunc:	截断文件
binary:	以二进制方式进行IO

在这里插入图片描述
以out模式打开文件会丢弃已有数据

默认情况下,打开一个ofstream时,文件的内容会被丢弃,阻止ofstream清空文件内容是同时指定app模式。
举例:
1.创建文件、清空文件内容
ofstream out(path);		//默认out模式
ofstream out(path,ofstream::out);

2.追加文件内容
ofstream out;			//默认out模式
out.open(path,ofstream::out | ofstream::app);
out<<"abc";
out.close();

3.string流

stringIO操作类型:
istringstream:	从string读取数据
ostringstream:	向string写入数据
stringstream:	读写都可以,继承自iostream

stringstream特有的操作:
sstream strm;		//strm是一个未绑定的stringstream对象
sstream strm(s);	//strm保存string s的一个拷贝,构造函数时explicit的
strm.str();			//返回strm所保存的string的拷贝
strm.str(s);		//将string s拷贝到strm中,返回void

*****使用istringstream和ostringstream*****
struct PersonInfo
{
	string name;
	vector<string> phones;
};

string path = "C:\\Users\\Administrator\\Desktop\\abc1.txt";
ifstream ii(path);
string line, word;
vector<PersonInfo> people;
while (getline(ii, line))		//从文件中读取每一行
{
	PersonInfo info;
	istringstream record(line);			//处理每一行string
	record >> info.name;				//第一个是名字
	while (record >> word)				//后面的是电话
		info.phones.push_back(word);
	people.push_back(info);
}
//打印
ostringstream out;
for (const auto& entry : people)
{
	out << "name:" << entry.name;
	for (const auto& nums : entry.phones)
	{ out<< " " << nums;}
	out<< "			";
}
cout << out.str() << fflush;	//输出
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值