C++ 11 (六)

1.流有着状态,IO库定义了一个与机器无关的iostate类型,它提供了表达流状态的完整功能,流有四种状态,badbit代表系统级错误,failbit表示一个IO操作失败,eofbit代表已经到了文件的结束,goodbit代表流是否发生错误,如果goodbit的值为0,那么就代表流未发生错误。

当我们使用如下的代码时:

while(cin >> word){}

实际上,我们这行代码就等价于!fail().我们应该使用good 或者是 fail 来确定流的总体状态。


2.我们可以自己管理流的状态:我们可以调用流的成员函数 rdstate(),这个函数可以得到一个类型为iostate的值,对应流的当前状态。我们还可以调用clear()函数,把流的状态置为有效(无论之前的状态是什么样),在调用clear()函数之后,我们再调用good()函数,一定可以得到一个true的值,代表我们的流的状态是有效的,我们也可以调用setstate()这个函数,来手动地改变流的状态。



3.管理输出缓冲:每一个输出流都管理着一个缓冲区,用来保存程序读写的数据.缓冲机制的作用:操作系统可以将程序的多个输出操作组合成单一的系统级写操作,会带来很大的性能提升。 缓冲刷新(概念):数据真正写到输出设备或者文件。

导致缓冲刷新的原因一般有:

1.程序正常结束,作为main函数的return操作的一部分。

2.缓冲区满时,需要刷新缓冲,之后新的数据才能继续写入缓冲区。

3.我们可以使用操纵符像endl,来显式刷新缓冲区。

4.使用unitbuf来设置流的内部状态,清空缓冲区。  cout << unitbuf;这一句就相当于所有输出操作后都会立即刷新缓冲区,cout << nounitbuf;这一句就相当于回到正常的缓冲方式。

5.一个输出流可能会被关联到一个流上面,在这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。


绑定两个流:X.tie(&o) 代表的是X流已经绑定到了输出流o上面,传入的参数是流的指针,而不是流的引用,我们假如要彻底解开流的关联,我们应该传递一个空指针(nullptr)。


4.文件的输入和输出:

两个关键点:1.文件流对象,2.文件名。可以在构造一个文件流对象的时候把文件名(可以是string类型的对象,也可以是C风格的指针)传入构造函数,直接打开文件,也可以手动调用文件流对象的open函数,open也是接受一个文件名参数。

一些代码:

file.h

#ifndef FILE_H
#define FILE_H

#include <iostream>
#include <string>
#include <fstream>
#include <vector>

std::vector<std::string> getFileContent(std::ifstream& in);

void outPutToFile(std::ofstream& out, const std::vector<std::string>& target);
	
#endif


file.cpp

#include "file.h"

std::vector<std::string> getFileContent(std::ifstream& in)
{
	std::vector<std::string> currentVector;
	std::string currentWord;
	while (in)
	{
		in >> currentWord;
		currentVector.push_back(currentWord);
	}
	return currentVector;
}

void outPutToFile(std::ofstream& out, const std::vector<std::string>& target)
{
	for (std::vector<std::string>::size_type i = 0; i != target.size(); ++i)
	{
		out << i << target[i] << std::endl;
	}
}



main.cpp

#include "file.h"

int main(int argc, char* argv[])
{
	std::string inputFile("./input.txt");
	std::string outputFile("./output.txt");
	std::ifstream in(inputFile);
	std::ofstream out(outputFile);
	if (in && out)
	{
		std::vector<std::string> current = getFileContent(in);
		oututPutToFile(out,current);
	}
	in.close();
	out.close();
	return 0;
}

编译: g++ --std=c++11 file.h file.cpp main.cpp  执行 ./a.out


我用来测试的文件里面的单词之间有1到多个空格,而且每一行的单词数量不一样,但是ifstream这个对象还是能正确地把每一个单词读入vector里面,因为直接使用ifstream对象的>>操作符,会默认把空格符,换行符自动当做分界符来处理,所以能正常运行。


5.在使用ifstream 和 ofstream 的时候 千万要检查流的状态,因为如果open失败,那么这个流的failbit 会被置位,good()会返回false,文件流对象也遵循作用域的规则:当一个fstream 对象被销毁时,close()会被自动调用。


6.文件模式:

1.in   读方式

2.out   写方式

3.app(append)    在每一次写文件之前定位到文件末尾

4.ate(at end)      在打开文件的时候就定位到文件末尾

5.trunc       截断文件

6.binary     以二进制方式进行IO

流的模式在这些中,但是要遵循一些条件:对应条件(输入就是in,不能是out...),默认条件(如果是out模式,那么文件默认被截断)特定条件(只有trunc没有被设定的时候,我们才能指定使用app模式,在app模式下,即使没有显式指定out,文件也总是以输出方式被打开)

如果没有指定app模式,那么输出文件的之前的数据都会被覆盖掉。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值