【C++】文件IO流

news2025/2/25 21:36:47

一起来康康C++中的文件IO操作吧

文章目录

  • 1.operator bool
  • 2.C++文件IO流
  • 3.文件操作
    • 3.0 关于按位与的说明
    • 3.1 ifstream
    • 3.2 ofstream
      • 流插入文本
    • 3.3 ostringstream/istringstream
    • 3.4 stringstream
    • 3.5使用stringstream的注意事项
  • 结语

1.operator bool

之前写OJ的时候,就已经用过上面这种方式来获取多组测试用例

string s;
while(cin>>s)
{
	cout << s << endl;
}

不过之前一直没有去了解这里的底层原理是什么,借此机会一并说明

io流可以进行while判断的依据,是因为库的源码中重载了operator bool

image-20221021083819728

没错,operator不仅可以重载一个操作符,它还可以重载一个类型!即将这个类转换为bool类型,return 一个bool类型的值用于while的判断

同理,重载int/double这些类型都是可行的!

另外,要想停止上面的多组输入,在VS下可以用ctrl+z的方式解决,而不要用ctrl+c直接杀掉进程


2.C++文件IO流

image-20221021084123029

C++的文件io类设计的较为复杂,其中还出现了菱形继承,也就是我们最常用的iostream

上面提到的operator bool就是基类IOS实现的,子类都没有去重写

  • cout为标准输出,将数据从内存流中输入到显示器上
  • cin为标准输入,通过键盘输入数据到程序中
  • cerr用于标准错误的输出
  • clog进行日志输出

其中需要注意的一点是,空格和回车会被当作数据之间的分隔符,所以字符串中不能有空格,回车和空格也不能通过cin读入

如果需要读入带空格的完整一行,可以使用getline函数

  • 为什么cin和cout可以输入输出所有类型?

因为库里面已经将所有类型通过操作符重载<<>>实现了,达到了自动类型识别的效果

3.文件操作

C++标准库中提供的打开方式如下,我们可以根据不同情况传入不同的值,或者一次性用按位或|传入多个打开方法

image-20221021131806044

同时因为C++类和对象会自动调用析构函数,所以我们也不需要手动close文件

3.0 关于按位与的说明

这里为何可以用按位与传入多个方法?

假设这些方法就是简单的数字2/4/8(必须是2的倍数)我们可以通过按位与了之后,在按位或,判断某一个数字是否在其中

image-20221021134429643

如果或了之后的数字等于它本身,说明数据在其中!

  • 为什么需要是2的倍数呢?

image-20221022102400142

这种方法在linux中常见,比如linux系统的文件接口

3.1 ifstream

image-20221021130324611

这个对象是用于读取文件的,默认情况下,传入的打开方法为in

void test1()
{
	ifstream ifs("test.txt");
	while (ifs)
	{
		char ch = ifs.get();
		cout << ch;
	}
}

image-20221021131949014

因为重载了bool,所以可以很方便的直接用while来判断结束,成功输出了文件中的内容

	ifstream ifs("test.txt");
	char ch;
	while (ifs >> ch)
	{
		cout << ch;
	}

第二种读取方法采用了流插入>>上面提到过,流提取和插入的时候,会把空格和换行当作数据的分隔符,所以它是不能打印出空格和换行

image-20221021132102499

3.2 ofstream

image-20221021200201898

写文件的方式同上,用out方法打开文件就可以了(默认传的就是out)

	ofstream ifs2("test1.txt",ios::out);
	char str[] = "i love u\n";
	ifs2.write(str,sizeof(str));

image-20221021133644760

不过这个和C语言的w方法一样,写入的时候会覆盖文件中已有的内容。如果想进行追加,则需要在后面加上app;如果是执行二进制读写,则需要与上ios::binary

	ofstream ifs2("test1.txt",ios::out|ios::app);
	char str[] = "i love u";
	ifs2.write(str,sizeof(str));

image-20221021133902913

运行成功后会在文件尾部追加内容

注意,这里的字符串不能用string进行处理,因为string内部只存了一个指向字符串空间的指针,写入string相当于把指针写入进文件中,是么有用的!

image-20221021135154450

流插入文本

但是,如果我们用<<进行提取的时候,就可以用string了

void test2()
{
	ifstream ifs("test.txt");
	ofstream ofs("test1.txt");

	char ch;
	ch = ifs.get();
	while (~ch)
	{
		ofs << ch;
		cout << ch;

		ch = ifs.get();
	}
	string s("i love you");
	ofs << s;
}

程序运行后,会把test.txt中的内容输出到控制台,同时写入到test1.txt

最后还会写入一个string的内容

image-20221021200810379

这是因为我们调用<<的时候,就和cin<<s一样,调用的是string重载的流提取操作符

底层实现的时候会将其转为C语言的字符串,从而写入到了文件中

所以当我们需要写入一个自定义类型的时候,可以重载流提取操作符,不仅可以更方便的打印,还可以写入到文件中


3.3 ostringstream/istringstream

这个类可以将不同的类型转为字符串

这种操作被称为序列化和反序列化,在处理自定义类型的时候非常好用

struct Date
{
public:
	friend ostream& operator << (ostream& out, const Date& d);
	friend istream& operator >> (istream& in, Date& d);
	Date(int y=0, int m=0, int d=0)
	{
		_year = y;
		_month = m;
		_day = d;
	}
private:
	int _year;
	int _month;
	int _day;
};


istream& operator >> (istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;
}

void test4()
{
	int i = 123;
	double d = 44.55;
	ostringstream oss;//序列化
	oss << i;
	string stri = oss.str();

	oss.str("");//清空oss
	oss << d;
	string strd = oss.str();
	cout << strd<< endl;

	oss.str("");//清空oss
	Date d1(2022, 10, 11);
	oss << d1;
	string strdt = oss.str();
	cout << strdt << endl;

	istringstream iss(strdt);//反序列
	Date d2;
	iss >> d2;
	cout << d2 << endl;
}

image-20221021202021334

3.4 stringstream

这个对象可以用于字符串拼接,也可以用来将其他类型转为str

	stringstream sstream;
	// 将多个字符串放入 sstream 中
	sstream << "first" << " " << "string,";
	sstream << " second string";
	cout << "strResult is: " << sstream.str() << endl;
	// 清空 sstream
	sstream.str("");
	sstream << "third string";
	cout << endl;
	cout << "After clear, strResult is: " << sstream.str() << endl;

image-20221021202846449

3.5使用stringstream的注意事项

  • stringstream实现转换,实际上是维护了一个string对象实现的

  • 我们可以使用str("")清空里面的string对象,设置为空字符串

  • 多次数据类型转换的时候,需要用clear()来清空,才能正确转换。不过clear()不会清空底层的string对象

  • 因为使用的是string对象,所以使用的时候不需要格式化控制,可以自动推导类型

stringstreams在转换结尾时(即最后一个转换后),会将其内部状态设置为badbit
因此下一次转换是必须调用clear()将状态重置为goodbit才可以继续转换

image-20221021203337884

这里在第一次调用stringstream操作后,我们没有进行clear,会发现后续的double类型转换失败了

image-20221021203409171

执行了clear之后,转换成功!

结语

关于C++IO流操作的基本认识到这里就over了。

因为在实际中用的并不算多,所以这部分的内容大多数是了解一二,知道如何使用,以及3.0中提到的按位与操作是怎么实现的就OK了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/361715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习-----排序问题1.0(冒泡排序、选择排序、插入排序)

目录 前言&#xff1a; 1.冒泡排序 2.选择排序 3.插入排序 前言&#xff1a; 学过C语言肯定接触过排序问题&#xff0c;我们最常用的也就是冒泡排序、选择排序、插入排序……等等&#xff0c;同样在Python中也有排序问题&#xff0c;这里我也会讲解Python中冒泡排序、选择排…

MvvmLight框架入门

MvvmLight MvvmLight主要程序库 ViewModelLocator 在.netFramework环境下nuget安装MvvmLight会自动安装依赖项MvvmLightLibs库&#xff0c;如果在.net core环境下需要手动安装MvvmLightLibs库。 .netFramework环境下安装完成后&#xff0c;在ViewModel目录下具有一个 ViewMo…

page cache设计及实现

你好&#xff0c;我是安然无虞。 page cache的设计及实现 page cache 本质上也是一个哈希桶, 它是按照页的数量进行映射的. 当 central cache 向 page cache 申请内存时, page cache 先检查对应位置是否有span, 如果没有则向更大页去寻找一个span, 如果找到则分裂成两个. 比如…

Java基础常见面试题(五)

异常 Java 异常类层次结构图概览 &#xff1a; Exception 和 Error 有什么区别&#xff1f; Java 中&#xff0c;所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类 Exception&#xff08;异常&#xff09;和 Error&#xff08;错误…

DAMA-CDGA/CDGP数据治理认证考试如何报考?

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

LocalDNS

目录 文章目录目录本节实战DNS优化1、dns 5s 超时问题解决办法2、NodeLocal DNSCache实验软件关于我最后本节实战 实战名称&#x1f498; 实战&#xff1a;NodeLocal DNSCache-2022.7.30(测试成功)&#x1f498; 实战&#xff1a;NodeLocal DNSCache-2023.2.21(测试成功) DNS优…

强大的内置数据结构_元组(6,)

如约而至&#xff0c;紧接着上一期文章&#xff0c;小编将会陆续把全套的Python笔记将依次发放给大家&#xff0c;便于大家学习Python、期末备考、巩固基础等(这几期是公众号小插曲&#xff0c;后期发放编程技术的话主要还是会围绕Java来展开~感谢大家支持)元组python内置数据结…

Vulnhub靶场----2、DC-2

文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-2下载地址&#xff1a;https://download.vulnhub.com/dc/DC-2.zip kali&#xff1a;192.168.144.148 DC-2&#xff1a;192.168.144.150 添加hosts文件&#xff1a;192.168.144.150 DC-2 二、渗透流程 nmap -A -…

FLV-初学总结

FLV-初学总结 从零开始仅学习了一下午的总结&#xff0c;本文非常稚嫩… 本文为纯初学者的学习记录&#xff0c;为了方便理解&#xff0c;内容未必严谨&#xff0c;可以用作纯新手的入门了解篇。本文主要的参考链接如下⬇️ 详细了解FLV&#xff1a;FLV官方文档&#xff08;Ve…

面向对象之三大特性(二)

5. 面向对象三大特性 继承、多肽、封装 5.1 继承 类的继承与现实生活中的父、子继承关系一样。被继承的类称为父类、基类或超类&#xff0c;继承者称为子类。Python 继承分为&#xff1a;单继承和多继承&#xff08;继承多个类&#xff09;。 class Parent1:pass class Par…

分析称勒索攻击在非洲、中东与中国增长最快

Orange Cyberdefense&#xff08;OCD&#xff09;于 2022 年 12 月 1 日发布了最新的网络威胁年度报告。报告中指出&#xff0c;网络勒索仍然是头号威胁 &#xff0c;也逐渐泛滥到世界各地。 报告中的网络威胁指的是企业网络中的某些资产被包括勒索软件在内的攻击进行勒索&…

Qt中修改界面类的类名时需要注意的几个修改点

有些时候因为一些原因&#xff0c;需要修改Qt中创建的界面类&#xff0c;需要特别注意几个修改点。 比如将test类修改为test2类 修改test.h名称为test2.h文件&#xff1b;修改test.cpp名称为test2.cpp文件&#xff1b;修改test.ui名称为test2.ui文件&#xff1b;修改pro文件中…

前端Docker部署方案

一、Docker容器和镜像概念 首先明确镜像和容器的概念。我们可以用 docker 构建一个镜像&#xff0c;这个镜像可以导入导出&#xff0c;用于传输&#xff0c;重复利用。然后如果把他 run 起来&#xff0c;则称为一个容器。容器是运行时&#xff0c;会包括运行时上下文&#xff…

Vue基础14之TodoList组件自定义事件、全局事件总线、TodoList全局事件总线

Vue基础14TodoList-组件自定义事件先改Header和Footer子组件&#xff0c;List先不考虑App.vueMyHeader.vueMyFooter.vue全局事件总线实现思路正规写法main.jsApp.vueStudent.vueSchool.vue总结&#xff1a;全局事件总线&#xff08;GlobalEventBus&#xff09;TodoList案例&…

【Java闭关修炼】MyBatis-接口代理的方式实现Dao层

【Java闭关修炼】MyBatis-接口代理的方式实现Dao层实现规则代码实现代理对象分析接口代理方式小结实现规则 映射配置文件中的名称空间必须和Dao层接口的全类名相同映射配置文件的增删改查标签的id属性必须和Dao层接口方法的参数相同映射配置文件中的增删改查标签的parameterTyp…

【C进阶】数据的存储

文章目录:star:1. 数据类型:star:2. 整形在内存中的存储2.1 存储规则2.2 存储模式2.3 验证大小端模式:star:3. 数据范围3.1 整形溢出3.2 数据范围的求解3.3 练习:star:4. 浮点型在内存中的存储4.1 浮点数的存储规则4.2 练习5. :star::star:总结(思维导图)⭐️1. 数据类型 在了…

独立产品灵感周刊 DecoHack #048 - 优秀独立开发产品推荐

如果有关注我的 Twitter 的朋友应该看到了&#xff0c;我上周末研究了两天 AI 画图&#xff0c;现在用 Ai 做图太强了&#xff0c;上周又升级 Stable Diffusion 玩了一下&#xff0c;和我去年试的时候相比强大了好多&#xff0c;而且插件LoRA模型玩法都还在快速迭代&#xff0c…

超详细解读!数据库表分区技术全攻略

更多内容可以关注微信公众号&#xff1a;老程序员刘飞 分区的定义 分区是一种数据库优化技术&#xff0c;它可以将大表按照一定的规则分成多个小表&#xff0c;从而提高查询和维护的效率。在分区的过程中&#xff0c;数据库会将数据按照分区规则分配到不同的分区中&#xff0…

【Linux】调试工具gdb的使用

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;前言在前文&#xff0c;我们已经讲解了vim工具以及gcc/g的使用&#xff0c;我们可以进行编写代码以及编译代码了&#xff0c;但是还没有学习如何在Linu…

贪心--跳跃问题/拼接问题

跳跃问题 判断能否从数轴的最左端跳跃到最右边 变形&#xff1a;最少跳跃次数 45.跳跃游戏 题目链接 给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示…