C++中流的分类

前言

关于流本质的问题,其实从我刚开始学习C++的时候,就已经存在了。当时找了不少的资料,不过一直处于那种知其然而不知其所以然的状态,关于流的本质问题我还是一直没有搞通,始终就是懵懵懂懂的。
不过在今天,我在一时兴起又在查阅流相关资料的时候,突然发现我貌似能够理解了它,因此用此篇博客来记录一下。
有一点需要事先声明一下,以下的内容,皆是我自己的理解,由于个人知识积累及阅历的原因,可能会存在一些不足,如果发现有错误,还请读者予以斧正。

流的理解

流的本质是一种对象

流是介于数据程序之间的一个中转设备。

因为流的存在,使得我们可以不需要直接操作数据,而是通过操作流的方式间接对数据进行操作。

流的优势

统一操作标准。

无论对于何种数据,以及数据的类型如何,只要将这个数据和流关联起来,那么我们就可以不用考虑数据到底是如何存储的,只需要按照流的操作标准来进行操作即可,这就是统一了操作标准。

上面说到,流的本质是一个对象,因此对于流而言,存在着许多的方法,这些方法为我们操作数据提供了统一的接口,对我们甚至可以做到在不更改代码的前提下,操作不同的数据。

C++中流的分类

C++中流的分类_第1张图片

C++中流主要分为三类:

  • IO流: 输入输出流,iostream
  • 文件流: 对于文件的操作,fstream
  • 字符串流: 主要实现对于字符串的操作,stringstream

IO流

C++中流的分类_第2张图片

这三者在本质上还是一样的,都是抽象出方法,只不过操作的对象不同罢了。以下贴出这几个类之间的关系图:

C++中流的分类_第3张图片

由上图可见,为什么说可以像使用cin/cout的方式去使用fstream,因为fstream本身是继承自iostream的。

字符串流sstream

基本概念

用内存中的string类型变量作为输入和输出的对象.。
特点:

  • 与标准输入输出流相同,能够进行文本与二进制之间的相互转换。
  • 向string存数据⇔ \Leftrightarrow⇔cout 二进制转为ASCII。
  • 从string取数据⇔ \Leftrightarrow⇔cin ASCII转为二进制。
  • 无需打开关闭。
  • 能够存放各种类型数据。

使用

#include 
ostringstream ostr;//输出流
istringstream istr;//输入流
stringstream str;//输入/输出流

sstring头文件定义了三个类型来支持内存IO操作,这些类型可以向string写入数据,从string读取数据,就像string是一个IO流一样。

istringstream从string读取数据,ostringstream向string写入数据,stringstream既可以向string写入数据也可以向string读取数据。

C++中流的分类_第4张图片

#pragma once
#include
#include
#include

class Stream {
public:
	Stream() {}
	Stream(std::string& str)
		:str_(str)
	{}
	~Stream() {};

	//输出流
	void OsStringStream();
	//输入流
	void IsStringStream();
	//输入输出流
	void StringStringStream();

protected:
	std::string str_;
};

#include"stream.h"

void Stream::OsStringStream() {
	std::ostringstream oss(str_);
	std::cout << oss.str() << std::endl;
}

void Stream::IsStringStream() {
	std::string line;
	std::istringstream iss(str_);
	std::getline(iss, line);
	std::cout << line << std::endl;

	//创建输入流
	std::istringstream str;
	//拷贝字符串到输入流中
	str.str("bye bye");
	//用str_str返回str.str()的拷贝
	std::string str_str = str.str();
	std::cout << str_str << std::endl;
}

void Stream::StringStringStream() {
	std::stringstream ss1(str_);
	std::cout << ss1.str() << std::endl;
}

#include"stream.h"

int main() {
	std::string str("ni hao");
	Stream stream(str);
	stream.IsStringStream();
	stream.OsStringStream();
	stream.StringStringStream();
	return 0;
}

文件流fstream

img

程序运行时,产生的数据都属于临时数据,程序一旦运行结束都会被释放,通过文件可以将数据持久化,C++对文件操作需要包含头文件 < f s t r e a m > 。文本类型分为两种:

(1)文本文件:文件以文本的ASCII码的形式存储在计算机中。
(2)二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂他们。

操作文件三大类:

  • ofstream:写

  • ifstream:读

  • fstream:读写

文本文件

写文件

步骤如下:

  • 包含头文件:#include< fstream>
  • 创建流对象:ofstream ofs;
  • 打开文件:ofs.open(“文件路径”,打开方式);
  • 写数据:ofs<<“写入的数据”;
  • 关闭文件:ofs.close();

打开方式:

C++中流的分类_第5张图片

在这里插入图片描述

注:文件打开方式可以配合使用,利用|操作符。

void Csv::WriteCsvFile() {
	//std::ofstream out_file("data.csv", std::ios::out); //std::ios::out 文件不存在则创建文件,有文件则清空文件
	std::ofstream out_file;
	out_file.open("data.csv", std::ios::out);
	if (!out_file) {
		std::cout << "open file failed" << std::endl;
		return;
	}
	for(int i = 0; i < 5; ++i) {
		out_file << 12 << ",";
		out_file << 13 << ",";
		out_file << 14 << std::endl;
	}
	out_file.close();
	std::cout << "write file successed" << std::endl;
}

在这里插入图片描述

读文件

步骤如下:

  • 包含头文件:#include< fstream>
  • 创建流对象:ifstream ifs;
  • 打开文件,并判断文件是否打开成功:ifs.open(“文件路径”,打开方式);
  • 读数据:四种读取方式
  • 关闭文件:ifs.close();

在这里插入图片描述

在这里插入图片描述

#pragma once
#include
#include
#include
#include

class Csv {
public:
	Csv() {}
	~Csv() {}
	void ReadCsvFile();
	void WriteCsvFile();
};

#include"csv.h"

void Csv::ReadCsvFile() {
	//std::ifstream in_file("data.csv", std::ios::in);
	std::ifstream in_file;
	in_file.open("data.csv", std::ios::in);
	if (!in_file) {
		std::cout << "open fill failed" << std::endl;
	}
	int num = 0;
	std::string line;
	std::string file;
	while (std::getline(in_file, line)) {
		std::string file;
		// 将整行字符串line读入到字符串流iss中
		std::istringstream iss(line);
		std::getline(iss, file, ',');
		//将刚刚读取的字符串转换成int
		std::cout << std::atoi(file.c_str()) << " ";
		std::getline(iss, file, ',');
		std::cout << std::atoi(file.c_str()) << " "; 
		std::getline(iss, file, ',');
		std::cout << std::atoi(file.c_str()) << std::endl;
		num++;
	}
	std::cout << "读取了" << num << "行" << std::endl;
	if (5 == num) {
		std::cout << "read file success" << std::endl;
	}
	in_file.close();
}

void Csv::WriteCsvFile() {
	//std::ofstream out_file("data.csv", std::ios::out);
	std::ofstream out_file;
	out_file.open("data.csv", std::ios::out);
	if (!out_file) {
		std::cout << "open file failed" << std::endl;
		return;
	}
	for(int i = 0; i < 5; ++i) {
		out_file << 12 << ",";
		out_file << 13 << ",";
		out_file << 14 << std::endl;
	}
	out_file.close();
	std::cout << "write file successed" << std::endl;
}

#include"csv.h"

int main() {
	Csv csv;
	csv.WriteCsvFile();
	csv.ReadCsvFile();
	return 0;
}

每个文件流都有一个默认的文件模式,ifstream关联的文件默认以in模式打开,ofstream关联的文件默认以out模式打开,fstream关联的文件默认以in和out模式打开。

ofstream out; // 未指定文件打开模式
out.open("test.txt"); // 模式隐含设置为输出和截断
out.close(); // 关闭out
out.open("test2.txt",ofstream::app); //模式为输出和追加
out.close(); //关闭out 

你可能感兴趣的:(c++)