news 2026/4/23 13:03:46

【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/23 10:45:04

如何在C++的STL中巧妙运用std::find实现高效查找

这篇文章展示如何在一个范围内搜索。这里坚持用标准版本的STL&#xff0c;并考虑由2个迭代器表示的范围。STL可以被分成两部分&#xff1a;对已排序元素进行操作的部分以及对未排序元素进行操作的部分。这种差异对搜索有两个影响:在已排序的集合中查找非常快&#xff0c;通常在…

作者头像 李华
网站建设 2026/4/18 8:16:31

【ISP】暗角阴影校正-Radial Shading

一、镜头阴影 当镜头与sensor匹配&#xff0c;因为Sensor感光区的边缘区域接收的光强比中心区域小&#xff0c;所造成的中心和四角亮度不一致的现象。镜头本身就是一个凸透镜&#xff0c;由于凸透镜原理&#xff0c;中心的感光必然比周边多。 镜头阴影不利于后期的画面分析&a…

作者头像 李华
网站建设 2026/4/9 8:31:13

具身智能抢人大战:毕业一年,年薪300万元

“AI让真正的天才价值体现出来了”。 具身智能的竞技场上&#xff0c;一场围绕顶尖人才的争夺战已经打响&#xff0c;其激烈程度与薪酬数字&#xff0c;正不断突破人们的想象。 最新的信号来自字节跳动。不久前&#xff0c;其旗下火山引擎释放出一则招聘信息&#xff1a;为招…

作者头像 李华
网站建设 2026/4/19 15:59:27

电力系统短期负荷预测(附Python代码+数据+详细文章讲解)

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

作者头像 李华