当前位置: 首页 > news >正文

《c++ primer笔记》第八章 IO库

前言

简单看一下就行

文章目录

    • 一、IO类
      • 1.1基本概念
      • 1.2管理输出缓冲
    • 二、文件输入输出
      • 2.1文件模式
    • 三、string流
      • 3.1istringstream
      • 3.2ostringstream

一、IO类

1.1基本概念

​ 我们常见的流有istream和ostream,这两个流都是有关输入和输出的,此外,下标列举了一些其它的IO类型fstream定义了读写命名文件的类型,sstream定义了读写内存string对象的类型。

image-20230306193240390

​ 不同IO类型之间虽然存在着差异,但是我们在使用时完全可以忽略。可以用>>读取数据,不管是从控制台窗口用户的输入、磁盘文件中读入还是读取一个字符串。标准库通过继承机制,忽略了这些差异(这部分在15章和18章有谈到,感觉这种知识点目前阶段可以不用去深究,知道怎么用就行)

IO对象没有拷贝或赋值

IO对象不能对其进行拷贝或者赋值,所有我们在编写函数时,不能将其作为形参或者返回类型。通常进行IO操作的函数以引用的方式传递和返回流

IO操作的条件状态

​ 书上列举很多使用IO操作时可能出现的条件状态,可以把它们理解为一个报错信息提醒。比如定义了一个整型变量,输入的确实一个字符串,这时就会出现IO操作失败的信息,一旦一个流发生错误,其后面跟着的IO操作都会失败

image-20230306194733222

确定一个流对象的状态的最简单的方法是将它当做一个条件来使用。

while (cin >> word)

如果我们要查询一个流的具体状态,可以通过iostate类型,它里面有4个constexpr值:badbit表示系统级错误,流无法再使用,比如不可恢复的读写错误;failbit就是上面提到了输入类型不匹配,这种情况是可以修正的,流可以继续使用;eofbit表示文件结束位置,这时failbit也会被置位;goodbit值为0表示流未发生错误。

1.2管理输出缓冲

​ 每个输出流都管理一个缓冲区,用来保存程序读写的数据。缓冲区机制可以让操作系统将程序的多个输出操作组合成单一的系统级写操作。

刷新输出缓冲区

​ 导致缓冲区刷新的条件有很多,如下:

  1. 程序正常结束,作为main函数的return操作的一部分
  2. 缓冲区满时,需要刷新才能写入新的数据
  3. 使用endl显式刷新缓冲区,还有flushends都可以刷新缓冲区
  4. 每个输出操作之后,可以使用操纵符unitbuf设置流的内部状态,来清空缓冲区(使用该操作会在输出后立即刷新缓冲区,适用于程序之后的所有输出,可以通过设置nounitbuf重置回到正常的缓冲方式)
  5. 两个关联的流在其中一个被读写时,另一个流的缓冲区会被刷新。比如cincerr都关联到cout,当读cin或者写cerr都会导致cout的缓冲区刷新(可以通过tie构建两个流之间的映射关系)

二、文件输入输出

image-20230306204952250

​ 当要读写一个文件时,可以定义个文件流对象,并将对象与文件关联起来。每个文件流类都定义了一个名为open的成员函数。

ifstream in(file); // 传入一个文件,open函数会被自动调用
in.close(); // 同样的,当我们销毁一个fstream对象时,close会自动被调用

2.1文件模式

​ 每个流都有一个关联的文件模式。

image-20230306205749628

对于上面的模式对流有一定的限制:

  • 只可以对ofstreamfstream对象设定out模式
  • 只可以对ifstreamfstream对象设定in模式
  • 只有当out被设定时才可以使用trunc模式。(即使没有指定trunc,以out模式打开的文件也会被截断)
  • 只要truc模式没被设定,就可以设定app模式。在app模式下。即使没有显式指定out模式,文件也总是以输出方式打开

每个文件流类型都定义了一个默认的文件模式,ifstream默认以in模式打开,ofstream默认以out打开,fstream默认以in和out打开。

​ 在只使用out时,打开的文件的内容会被清空,所以需要加上app模式把新的内容添加到文件末尾。

三、string流

image-20230306211123680

3.1istringstream

​ 处理文本或者单个单词可以使用。

struct PersonInfo {string name;vector<string> phone;
}int main() {string line, word;vector<PersonInfo> people;while (getline(cin, line)) { // 读取一行输入PersonInfo info;istringstream record(line); // 把读取的输入存到istringstream流中record >> info.name; // 读取名字while (record >> word) // 读取电话号码 line中含有名字和电话号码,这里意思就是把剩余的文件,也就是电话号码,读取出来用word代替info.phones.push_back(word);people.push_back(info);}
}

3.2ostringstream

​ 用于输出文本等操作。比如上面我们已经读入若干人的姓名和电话号码,需要逐个验证号码的正确性并输出。

for (const auto &entry : people) { // 循环读取每个人的信息ostringstream formatted, badNums; // 定义两个流分别保存正确和错误信息for (const auto &nums : entry.phones) { // 检查号码的正确性if(!valid(nums)) {badNums << " " << nums; // 存入流}else {formatted << " " << format(nums) // 存入流}}...//打印错误的和正确的内容...if(badNums.str().empty())os << entry.name << " " << formatted.str() << endl;elsecerr << "Input error:" << entry.name << " invalid number(s) " << badNums.str() << endl;
}
http://www.lryc.cn/news/31849.html

相关文章:

  • web开发 用idea创建一个新项目
  • 【FMCW 03】测速
  • ERP(企业资源管理)概述
  • 深入理解java虚拟机精华总结:性能监控和故障处理工具、类加载机制
  • 推荐系统与推荐算法
  • socket 编程实战(编写客户端程序 )
  • “巨亏成名”的魔鬼交易员,你知道几个?
  • 1380:分糖果(candy)
  • 数据挖掘(2.1)--数据预处理
  • PMP考前冲刺3.06 | 2023新征程,一举拿证
  • buuctf-pwn write-ups (11)
  • 【VTK】VTK隐藏vtkOutputWindow窗口的正确方法
  • 顺序表以及链表的应用及区别(包含OJ讲解)
  • JVM简介
  • Leetcode.1653 使字符串平衡的最少删除次数
  • leetcode 71~80 学习经历
  • 使用metrics-server监控k8s的资源指标
  • 【Copula】考虑风光联合出力和相关性的Copula场景生成(Matlab代码实现)
  • 【java基础】泛型程序设计基础
  • 【省选模拟测试23 T1直径】更好的做法
  • SpringCloud基础(3)-微服务远程调用
  • 10.单点登录原理及JWT实现
  • 图表控件LightningChart.NET 系列教程(十一):LightningChart 组件——添加至 Blend WPF 项目
  • libGDX:灯光效果实现一(实现一个点光源)
  • Java生态/Redis中如何使用Lua脚本
  • 网络编程 socket 编程(一)
  • 【SpringCloud】SpringCloud教程之Nacos实战(一)
  • 高通Android 12/13 默认应用程序授予权限
  • 代码随想录|day6|哈希表篇-- 242.有效的字母异位词 、349. 两个数组的交集 、202. 快乐数、1. 两数之和
  • k8s学习之路 | Day20 k8s 工作负载 Deployment(下)