news 2026/4/18 7:57:21

【C++】IO流详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++】IO流详解

C语言中我们用到的最频繁的输入输出方式就是 scanf() 和 printf()。

scanf():从标准输入设备(键盘)读取数据,并将值存放在变量中。

printf():将指定的文字/字符串输出到标准输出设备(屏幕)。注意宽度输出和精度输出控制。

除此之外,C语言借助了相应的缓冲区来进行输入和输出。如下图所示:

输入输出缓冲区的理解:

1.可以屏蔽掉低级I/O的实现,低级 I/O 的实现依赖操作系统本身内核的实现,所以如果能够屏蔽这部分的差异,可以很容易写出可移植的程序

2.可以使用这部分的内容实现 “行” 读取的行为,对于计算机而言是没有 “行” 这个概念,有了这部分,就可以定义“行”的概念,然后解析缓冲区的内容,返回一个“行”。

Ⅱ. 流是什么

“流” 即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续具有方向性的数据(其单位可以是bitbytepacket)的抽象描述。

C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。

🐛 它的特性是:有序连续具有方向性

为了实现这种流动,C++定义了I/O标准类库,这些每个类都称为流/流类,用以完成某方面的功能

Ⅲ. C++IO流

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios

📆 其中值得注意的是cerrclog是很少用的,它们本来是用做错误输出日志输出的,但是因为cout也能做到,所以这两个很少被使用。

  • <iostream>标准IO流

    • 对于cin:在 C++ 中称为流提取,也就是在 IO流 中提取信息,比如说读文件、获取键盘的信息等

    • 对于cout:在 C++ 中称为流插入,也就是在 IO流 中插入信息,比如说写文件、将信息输出到屏幕等

  • <fstream>文件IO流,支持通过流的方式来读写文件

    • 对于fstream既支持读也支持写文件经常用,而另外三个比较少用,因为这个功能比较多!

  • <sstream>:用来支持字符串的序列化与反序列化,多用于网络,与流关系不大

    • 对于stringsream:字符串常用这个

我们来研究下面这两段代码:

代码一:

展开

代码语言:C++

自动换行

AI代码解释

struct Student { string _name = "liren"; int _age = 20; }; ​ int main() { Student s; cin >> s._name >> s._age; cout << "名字:" << s._name << " 年龄:" << s._age << endl; ​ scanf("%s%d", s._name.c_str(), &s._age); printf("名字:%s 年龄:%d\n", s._name.c_str(), s._age); return 0; }

这段代码看上去没有什么问题,但如果我们第二次输入的字符串过长,会导致程序崩溃,原因如下 :

string内部会有一个_Buf数组,当存储的字符串大小小于 15 字节时,不会去堆上开辟空间存储字符串,会将字符串存储在_Buf数组中,但无论第一次输入的字符串大小是大于 15 字节还是小于 15 字节,第二次如果输入过长,都会导致程序崩溃,原因在于第二次是用scanf进行输入,使用scanf输入,不会影响stringsizecapacity,因为string中只重载了>><<,所以输入过长就会越界写入!

代码二:

展开

代码语言:C++

自动换行

AI代码解释

struct Student { string _name = "liren"; int _age = 20; }; ​ int main() { Student s; ​ cin >> s._name >> s._age; printf("名字:%s 年龄:%d\n", s._name.c_str(), s._age); cout << "名字:" << s._name << " 年龄:" << s._age << endl; ​ scanf("%s%d", s._name.c_str(), &s._age); printf("名字:%s 年龄:%d\n", s._name.c_str(), s._age); cout << "名字:" << s._name << " 年龄:" << s._age << endl; ​ return 0; }

这段代码和上一段代码相比只是最后的输出使用了cout,跟上面一样,如果输入过长也会导致越界写入,除此之外,就算输入的长度在合法的范围内,打印出来的结果也不是我们想要的,原因是cout在输出时是根据stringsize来输出的,而scanf输入时并没有改变** string** 的size,所以打印结果不是我们想要的,上面的printf如果输入的长度在合法的范围内,打印结果就是我们想要的,原因是printf打印字符串时是根据\0的位置来判断的。

为了解决这两个问题,我们需要提前为string变量扩容:

展开

代码语言:C++

自动换行

AI代码解释

struct Student { string _name = "liren"; int _age = 20; }; ​ int main() { Student s; ​ cin >> s._name >> s._age; printf("名字:%s 年龄:%d\n", s._name.c_str(), s._age); cout << "名字:" << s._name << " 年龄:" << s._age << endl; ​ s._name.resize(100); //提前扩容! ​ scanf("%s%d", s._name.c_str(), &s._age); printf("名字:%s 年龄:%d\n", s._name.c_str(), s._age); cout << "名字:" << s._name << " 年龄:" << s._age << endl; ​ return 0; } ​ 🚩 运行结果: liren 15 名字:liren 年龄:15 名字:liren 年龄:15 lirendada 15 名字:lirendada 年龄:15 名字:lirendada 年龄:15

总结:建议在C++中尽量去用cincout,用coutcin不方便的地方,再去用scanfprintf(格式控制输出时)

1. C++标准IO流

C++ 标准库提供了 4 个全局流对象 cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中,同时 C++ 标准库还提供了cerr用来进行标准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog 是 ostream 类的三个不同的对象,因此这三个对象现在基本没有区别,只是应用场景不同。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 22:05:04

Python+Vue的基于数据挖掘技术的线上招聘信息分析 Pycharm django flask

这里写目录标题项目介绍项目展示详细视频演示感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff08;免费咨询指导选题&#xff09;&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;希望帮助更多的人技术栈文章下方名片联系我即可~解决的思路…

作者头像 李华
网站建设 2026/4/11 11:58:23

理光 210开机报sc559代码故障如何维修

理光 210 开机报sc559&#xff0c;无法启动&#xff0c;不能工作&#xff1b;&#xff08;故障代码如下图&#xff09;&#xff1a;理光210开机报维修呼叫-SC559&#xff0c;经分析一般情况下 sc5xx的代码都是定影问题&#xff1b;今天看下这台具体是哪里的问题&#xff0c;把定…

作者头像 李华
网站建设 2026/4/16 13:40:54

提示工程在在线课程中的魔法:提示工程架构师的手笔

提示工程在在线课程中的魔法&#xff1a;提示工程架构师的手笔 一、引言&#xff1a;当在线课程遇到“提示魔法” 你是否遇到过这样的在线课程困境&#xff1f; 学生留言&#xff1a;“老师&#xff0c;这个知识点我听不懂&#xff0c;能不能再讲一遍&#xff1f;”但课程视频早…

作者头像 李华
网站建设 2026/4/18 5:40:03

leetcode 841. Keys and Rooms 钥匙和房间-耗时100%

Problem: 841. Keys and Rooms 钥匙和房间 解题过程 耗时100%&#xff0c;深度优先搜索dfs&#xff0c;标记已经访问过的node&#xff0c;最后看是否存在node没有访问过 Code class Solution { public:vector<bool> status;void dfs(int start, vector<vector<int…

作者头像 李华
网站建设 2026/4/17 10:33:34

华为2025年失败的手机是pura80?其实是开始阶段的鸿蒙5系统

华为论坛 2025年手机销量大战&#xff1a;华为能否逆袭vivo&#xff1f;鸿蒙5系统拖累Pura80、Nova14销量&#xff0c;但下半年鸿蒙6力挽狂澜。华为旗舰机强势&#xff0c;中端机乏力&#xff0c;2026年冲击6000万部目标关键在Pura90能否破千万销量。 各位手机圈的吃瓜群众们&a…

作者头像 李华
网站建设 2026/4/16 10:44:47

vue+uniapp+基于微信小程序的食堂预约点餐系统的设计与实现_36444434--论文

文章目录摘要主要技术与实现手段系统设计与实现的思路系统设计方法java类核心代码部分展示结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 随着移动互联网技术的快速发展&#xff0c;微信小程序凭借其轻量化、便捷性等特点&…

作者头像 李华