C++IO流

文章目录

  • 一、标准IO流
  • 二、文件IO流
    • 2.1 文件读写方式
    • 2.2 实现对自定义类的输入和输出
  • 三、stringstream流
    • 3.1 将数值类型数据格式化为字符串
    • 3.2 字符串拼接


一、标准IO流

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类。
C++IO流_第1张图片
C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了cerr用来进行标准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象,因此这三个对象现在基本没有区别,只是应用场景不同。

注意点:

  1. cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据。
  2. 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。
  3. 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入。
  4. cin和cout可以直接输入和输出内置类型数据,原因:标准库已经将所有内置类型的输入和输出全部重载了
  5. 对于自定义类型,如果要支持cin和cout的标准输入输出,需要对<<和>>进行重载。

二、文件IO流

对文件的输入和输出和使用cout和cin类似,把读入的键盘和输出的显示器转换为文件即可。

2.1 文件读写方式

C++根据文件内容的数据格式分为二进制文件和文本文件。采用文件流对象操作文件的一般步骤:

  1. 定义一个文件流对象
作用范围
ifstream ifile 输入用
ofstream ofile 输出用
fstream iofile 输入或输出用
  1. 使用文件流对象的成员函数打开一个磁盘文件,使得文件流对象和磁盘文件之间建立联系
打开方式 功能
in (input) 以读的方式打开文件
out (output) 以写的方式打开文件
binary (binary) 以二进制方式对文件进行操作
ate (at end) 输出位置从文件的末尾开始
app (append) 以追加的方式对文件进行写入
trunc (truncate) 先将文件内容清空再打开文件
  1. 使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写
成员函数 功能
put 插入一个字符到文件
write 插入一段字符到文件
get 从文件提取字符
read 从文件提取多个字符
tellg 获取当前字符在文件当中的位置
seekg 设置对文件进行操作的位置
>>运算符重载 将数据形象地以“流”的形式进行输入
<<运算符重载 将数据形象地以“流”的形式进行输出
  1. 关闭文件 ,类的成员函数close()

对数据的读取和写入

void test1()
{
	ofstream ofs("./test.txt", ofstream::out);//以写的方式打开,也可不写默认也是这种方式
	//也可以这样打开 
	//ofstream ofs; 
	//ofs.open("./test.txt", ofstream::out)
	person ps;
	ofs << ps.name << " " << ps.id << " " << ps.age;//写入空格区分,方便读取
	ofs.close();
}
//如果要使用多种打开方式可以使用或位运算符,因为每一种打开方式只占一个权值
	ofstream ofs("./test.txt", ofstream::out|ofstream::app);
void test2()
{
	ifstream ifs("./test.txt", ifstream::in);
	person ps;
	ifs >> ps.name >> ps.id >> ps.age;
	ifs.close();

	cout << ps.name << " " << ps.id << " " << ps.age << endl;
}

2.2 实现对自定义类的输入和输出

#include
#include
#include
using namespace std;

class Date
{
	friend istream& operator>>(istream& is, Date& date);
	friend ostream& operator<<(ostream& os, const Date& date);
public:
	Date(int _year = 2000, int _month = 1, int _day = 1)
		:year(_year), month(_month), day(_day)
	{}

private:
	int year;
	int month;
	int day;
};
ostream& operator<<(ostream& os, const Date& date)
{
	os <<  date.year << "-" << date.month << "-" << date.day << '\n';
	return os;
}

istream& operator>>(istream& is, Date& date)
{
	is >> date.year >> date.month >> date.day;
	return ifs;
}
int main()
{
	/*Date d1;
	Date d2(2022, 4, 6);
	ofstream ofs("./test.txt", ofstream::out);
	ofs << d1 << d2;*/

	Date d3;
	Date d4;
	ifstream ifs("./test.txt");
	ifs >> d3 >> d4;
	cout << d3 << d4;
	return 0;
}

C++IO流_第2张图片

三、stringstream流

在程序中如果想要使用stringstream,必须要包含头文件。在该头文件下,标准库三个类:istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作,本文主要介绍stringstream。

3.1 将数值类型数据格式化为字符串

void test1()
{
	int a = 123456789;
	string sa;
	stringstream s;

	s << a;
	s >> sa;
	cout << sa << endl;

	//s.clear();//不使用的话不能再读入
	double d = 3.14159;
	s << d;
	s >> sa;
	cout << sa << endl;;

}

两个输出相同
C++IO流_第3张图片
使用clear()函数后
C++IO流_第4张图片

来分析一下clear的作用

stringstream 的clear()函数

原型: void clear (iostate state = goodbit);
标志位一共有4种, goodbit, eofbit, failbit, badbit
clear可以清除掉所有的error state

原因在于, s2在第一次调用完operator<<和operator>>后,来到了end-of-file的位置,此时stringstream会为其设置一个eofbit的标记位,标记其为已经到达eof。查文档得知, 当stringstream设置了eofbit,任何读取eof的操作都会失败,同时,会设置failbit的标记位,标记为失败状态。所以后面的操作都失败了,toAdd的值一直都是1

函数str()的两种用法

  1. str()获得流对象里面的字符串
  2. str(“”)清空stringstream对象内容

3.2 字符串拼接

void test2()
{
	stringstream s;
	s << "first" << ",second" << ",third";

	cout << s.str() << endl;

	s.str("");//清空
	s << "1231231";

	cout << s.str() << endl;
}

C++IO流_第5张图片

clear()重置流的标志状态;str(“”)清空流的内存缓冲,重复使用内存消耗不再增加!


你可能感兴趣的:(C++,C++,文件)