《C++ Primer》第8章 IO库

news2024/11/26 4:42:20

参考资料:

  • 《C++ Primer》第5版
  • 《C++ Primer 习题集》第5版

8.1 IO类(P278)

我们目前使用过的 IO 对象(cincout)都是关联到控制台窗口、操纵 char 数据的。有时,我们需要对命名文件或者 string IO 操作。为了支持不同种类的 IO 操作,标准库定义了一些 IO 类型:

4867a8b265d1052cb95a861bed4a234

IO类型间的关系

概念上,设备类型和字符大小不会影响我们要执行的 IO 操作,例如我们可以用 >> 读取数据,这是通过**继承机制(inheritance)**实现的。

8.1.1 IO对象无拷贝或赋值(P279)

我们不能拷贝或对 IO 对象赋值,进行 IO 操作的函数通常以引用的方式传递和返回流。读写 IO 对象会改变其状态,所以传递和返回的引用不能是 const 的。

8.1.2 条件状态(P279)

IO 操作可能发生不同类型的错误,IO 类定义了一些函数和标志,可以帮助我们访问和操纵流的条件状态(condition state)

例如我们使用输入运算符并期待读入一个 int ,而实际上却得到了一个字符 B ,此时输入流将进入错误状态。只有当一个流处于无错状态时,我们才可以向它读写数据。最简单的判断流对象是否处于良好状态的方法:

while(cin >> word){ ... }

查询流的状态

IO 库定义了一个机器无关的 iostate 类型,提供表达流状态的完整功能。iostate 应该作为位集合来使用,IO 库定义了 4 个特定 constexpr 来表示特定的位:

  • badbit 表示系统级错误,通常为不可恢复的读写错误。
  • failbit 表示可恢复错误,如期望读取数值却得到字符。
  • eofbit 表示文件结束,此时 failbit 也会被置位。
  • goodbit0 表示流未发生错误(个人推测,前 3 个位在正常状态下位 0goodbit 就是它们的)。

标准库还定义了一组函数来查询上述标志位的状态:

  • good 在所有错误位均未被置位的情况下返回 true
  • badfaileof 在对应位被置位时返回 true ,此外,failbadbit 被置位时也会返回 true

管理条件状态

auto old_state = cin.rdstate();
cin.clear();
cin.setstate(old_state);
// 将failbit、badbit复位,其他位保持不变
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);

上述代码中,rastate 函数返回一个 iostate 值,对应当前流的状态setstate 相当于把输入的 iostate “叠加”到流的原状态上,可以理解为或运算;无参数的 clear 复位所有错误标志位,带参数的 clear 接受一个 iostate 参数,表示流的新状态

8.1.3 管理输出缓冲(P281)

每个输出流都有一个缓冲区,用来保存程序读写的数据。保存在缓冲区中的数据可能随后再打印。

导致缓冲刷新(数据真正写到输出设备或文件)的原因:

  • 程序正常结束,作为 main 函数 return 操作的一部分。
  • 缓冲区满。
  • 使用操纵符(如 endl )显式刷新缓冲区。
  • 使用操纵符 unitbuf 设置流的内部状态。cerr 是默认 unitbuf 的,因此写到 cerr 里的内容是立即刷新的。
  • 和输入流关联的输出流在输入流读取数据前会刷新缓冲区。

刷新输出缓冲区

cout << "hi" << endl;    // 输出hi和一个换行,然后刷新缓冲区
cout << "hi" << ends;    // 输出hi和一个空字符,然后刷新缓冲区
cout << "hi" << flush;    // 输出hi,然后刷新缓冲区

unibuf操纵符

cout << unitbuf;    // 将流设置为:接下来每一次写操作之后都进行一次flush操作
cout << nounitbuf;    // 回到正常的缓冲方式

如果程序异常终止,缓冲区是不会刷新的。所以我们在调试崩溃的程序时,需要检查输出是否停留在缓冲区内。

关联输入和输出流

当一个输入流被关联到一个输出流时,任何试图从输入流中读取数据的操作都会先刷新输出流的缓冲区。标准库将 cincout 关联在一起。

// 将cin关联到cout(仅仅用来展示,相当于什么都没有做)
cin.tie(&cout);
ostream *old_tie = cin.tie();
// 让cin不与任何流关联
cin.tie(nullptr);
// 将cin关联到cerr
cin.tie(&cerr);
cin.tie(old_tie);

tie 的无参数版本返回指向输出流的指针,如果本对象关联到一个输出流,则返回那个输出流的指针;如果本对象没有关联的输出流,则返回 nullptrtie 的单参数版本接受一个指向输出流的指针,将自己关联到此输出流。

每个流最多与一个流关联,但多个流可以同时关联到一个输出流(单向关联)。

8.2 文件输入输出(P283)

头文件 fstream 定义了三个类型来支持文件 IO :

  • ifstream :从一个给定文件读取数据。
  • ofstream:向一个给定文件写入数据。
  • fstream :读写给定文件。

除了继承自 iostream 的操作外,fstream 中还定义了一些新的成员:

88282ac734807eb1312cf041dd6917f

8.2.1 使用文件流对象(P284)

当我们想要读写一个文件时,可以定义一个文件流对象,并将之与文件关联起来。每个文件流类都定义了名为 open 成员函数来定位并以指定模式打开文件。创建文件流对象时,如果我们提供了文件名,则 open 会自动调用:

ifstream in(ifile);    // 构造一个ifstream并打开文件
ofstream out;

在 C++ 新标准中,文件名可以是 string 对象或 C 风格字符数组,旧版本的标准库只允许 C 风格字符数组。

fstream代替iostream&

在要求使用基类对象的地方,我们可以用继承类对象代替。这意味着一个接受 iostream 类型引用或指针参数的函数,可以用相应的 fstream 对象代替。

成员函数openclose

ifstream in(ifile);    // 构造一个ifstream并打开文件
ofstream out;
out.open(ifile + ".copy");

如果 open 调用失败,fallbit 会被置位。检测 open 是否成功是个好习惯:

if(out)

当一个文件流与对应文件成功关联,我们称文件流已经打开。用一个已经打开的文件流调用 open 会导致 failbit 被置位。所以如果我们将文件流关联到另一个文件,我们必须先使用 close 关闭当前文件:

in.close();

自动构造和析构

当一个 fstream 对象被销毁时,close 会自动调用。

8.2.2 文件模式(P286)

每个流都有一个关联的文件模式(file mode),用来指出如何使用文件:

8dd48df77fd3770cccad59711ee93e0

无论用哪种方式打开文件,我们都可以指定文件模式:

  • 只有 ofstreamfstream 能使用 out 模式。
  • 只有 ifstreamfstream 能使用 in 模式。( VS2022 似乎没这两条限制?这两条似乎与后面的冲突啊 … )
  • 只有当 out 模式被设定时,trunc 模式才能被设定。
  • 只要 trunc 模式没被设定,就可以设定 app 模式。在 app 模式下,文件综艺输出方式打开。
  • 默认情况下,以 out 模式打开的文件会默认被截断,为了保留文件内容,可以同时指定 addin 模式。
  • atebinary 模式可以用于任何类型的文件流对象。

每个文件流类型都有默认的文件模式,如果我们没有指定文件模式,就使用此模式。ifstream 默认使用 in 模式,ofstream 默认使用 out 模式,fstream 默认使用 inout 模式。

out模式打开会丢失数据

默认情况下,我们用 ofstream 对象打开文件时,文件内容的会被丢弃。

每次调用open时会确定文件模式

对于一个给定的流,每当打开文件时都可以改变文件模式。

8.3 string

sstream 头文件定义了三个支持内存 IO :

  • istringstream :从 string 读取数据。
  • ostringstream :向 string 写入数据。
  • stringstream :读写 string 数据。
00ba1c34d964732f0a72393165ce4ad

8.3.1 使用istringstream

假设我们要处理一个文件,文件的内容时人名和他们使用的电话号码:

morgan 2015552368 8625550123
drew 973550130
lee 6095550132 2015550175 800555000

我们首先定义一个类来保存数据:

struct PersonInfo {
	string name;
	vector<string> phones;
};

然后完成程序:

string line, word;
vector<PersonInfo> people;
while (getline(cin, line)) {
    PersonInfo info;
    istringstream record(line);
    record >> info.name;
    while (record >> word) {
        info.phones.push_back(word);
    }
    people.push_back(info);
}

8.3.2 使用ostringstream(P289)

接上面的例子,如果我们希望逐个验证电话号码并改变其格式 ,并将改变格式后的有效代码输出,并打印无效号码的错误信息:

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())
			cout << entry.name << " " << formatted.str() << endl;
		else
			cerr << "input error: " << entry.name << "invalid number(s)" << badNums.str() << endl;
	}
}

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

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

相关文章

iOS如何通过在线状态来监听其他设备登录的状态

前提条件 1、完成 3.9.1 或以上版本 SDK 初始化 2、了解环信即时通讯 IM API 的 使用限制。 3、已联系商务开通在线状态订阅功能 实现方法 你可以通过调用 subscribe 方法订阅自己的在线状态&#xff0c;从而可以监听到其他设备在登录和离线时的回调&#xff0c;示例代码如下…

【源码】自制链接表管理器

hi&#xff0c;大家好呀&#xff01; 前几天更新了个视频&#xff0c;教大家做了一个链接表的管理器&#xff0c;今天把文字内容给到大家&#xff0c;至于什么原因需要自己做一个链接表管理器&#xff0c;我在视频中有讲到&#xff0c;因为系统自带的链接表管理器没有筛选功能…

回归预测 | Matlab实现PCA-PLS主成分降维结合偏最小二乘回归预测

回归预测 | Matlab实现PCA-PLS主成分降维结合偏最小二乘回归预测 目录 回归预测 | Matlab实现PCA-PLS主成分降维结合偏最小二乘回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现PCA-PLS主成分降维结合偏小二乘回归预测&#xff08;完整源码和数据) 1.输…

直面LED Driver测试挑战,助力显示屏行业变中求变!

杭州亚运会开幕式惊艳世界&#xff0c;引发社会各界一致赞誉&#xff01;在大气浪漫的舞台效果中&#xff0c;LED屏、裸眼3D屏凭借“硬核科技”出圈&#xff0c;为大家带来科技、活力、诗意的“中国式浪漫”观赏体验。而这美轮美奂的LED呈现效果背后&#xff0c;主要依靠的是LE…

Echarts仪表盘自定义数值样式

需求描述 原图样式 需求样式 解决方案 {name: 数值,type: gauge,startAngle: 180,endAngle: 0,radius: 30%,center: [50%, 55%], // 默认全局居中 min: 0,max: 4,zlevel: 2,splitNumber: 0,axisLine: { // 坐标轴线 lineStyle: {color: [[1, ]], // 属性lineStyle控制线…

TSINGSEE视频智能分析系统AI算法针对遛狗不拴绳行为的监管方案

一、背景与需求 近期&#xff0c;一则恶犬咬伤女童的新闻上了热搜&#xff0c;因为狗主人没有给狗拴绳&#xff0c;导致小区内一女童被大型犬撕咬&#xff0c;女童全身多处咬伤&#xff0c;已入院治疗。该新闻曝出后立刻引发社会关注。遛狗不拴绳行为也再一次引发热议。因为狗主…

spring基础,编写第一个程序

spring基础 前言SpringSpring概述Spring的8大模块Spring特点学习spring6软件版本Spring的入门程序第一个Spring程序 小结 前言 控制反转&#xff0c;是面向对象编程中的一种设计思想&#xff0c;可以用来降低代码之间的耦合度&#xff0c;符合依赖倒置原则。 控制反转的核心是…

06、SpringBoot+微信支付 -->商户定时查订单状态、用户取消订单(关闭订单API)、查询订单API--到微信支付平台查询订单

目录 Native 下单、取消订单订单功能完善需求1&#xff1a;商户定时查单前端代码&#xff1a;后端代码&#xff1a;测试&#xff1a;swagger 测试&#xff1a; 需求2&#xff1a;用户取消订单&#xff08;关闭订单API&#xff09;需求&#xff1a;代码&#xff1a;前端&#xf…

Linux安装Python3.10与部署flask项目实战详细记录

java开发新手入门Python,创建flask后端服务对外提供访问.记录一下在阿里云服务器部署flask项目的操作过程,简单介绍一下使用的阿里云服务器系统配置:ubantu16.04,其他内核版本操作部分命令会有所区别,下面开始详细操作过程! 1.pycharm创建flask项目并打包 2.Python3.…

grafana 密码忘记怎么重置

1.重置密码的命令&#xff1a; grafana-cli admin reset-admin-password 新的密码

【JavaEESpring】Spring, Spring Boot 和Spring MVC的关系以及区别

Spring, Spring Boot 和Spring MVC的关系以及区别 Spring&#xff1a;简单来说&#xff0c;Spring 是一个开发应用框架&#xff0c;什么样的框架呢&#xff1f;轻量级、一站式、模块化&#xff0c;其目的是用于简化企业级应用程序开发 Spring的主要功能: 管理对象, 以及对象之…

收银系统有哪些分类 收银软件有哪些类型

收银系统有以下这几种分类&#xff0c;你都清楚么&#xff1a; 一、按是否能数据共享可分为&#xff1a;单机版收银系统、网络版收银系统 这里需要注意&#xff0c;很多地方说单机也能收银&#xff0c;其实单机和网络版只是数据存储地方不同&#xff0c;单机版需要在线收银还是…

2023第六届泰迪杯数据分析,第五届泰迪杯数据分析技能赛B题源码图片分享

需要B题源码以及第六届带队”指导“请私信本人&#xff0c;团队包含技能赛双一等&#xff0c;数学建模省一&#xff0c;泰迪杯挖掘国一&#xff0c;研究生队友。 去年一等作品可视化图如下&#xff0c;私信获取源码

javaSE学习笔记(五)集合框架-Collection,List,Set,Map,HashMap,Hashtable,ConcurrentHashMap

目录 四、集合框架 1.集合概述 集合的作用 集合和数组的区别 集合继承体系 数组和链表 数组集合 链表集合 2.Collection 方法 集合遍历 并发修改异常 3.List List集合的特有功能&#xff08;核心是索引&#xff09; 集合遍历 并发修改异常产生解决方案ListIterato…

在虚拟机中新安装的Linux无法联网解决办法

1、我们在虚拟机中新安装了linux&#xff0c;默认是无法连接网络的&#xff0c;这个时候&#xff0c;需要配置自动获取ip的网设置。 2、我们在VMware Workstatio需要配置net网络&#xff0c;如下图 3、进入linux系统&#xff0c;找到 /etc/sysconfig/network-scripts/ [rootn…

腾讯待办关停怎么办?可将导出的ics文件添加到手机待办APP中

有不少网友之前一直使用微信中的“腾讯待办”小程序来记录待办事项并设置定时提醒时间&#xff0c;但是最近一段时间在使用腾讯待办的时候&#xff0c;却发现主页弹出了“业务关停通知”&#xff0c;主要内容是&#xff1a;由于业务发展方向调整&#xff0c;腾讯待办将于2023年…

下载文本标注工具doccano遇到的报错以及解决方案

下载文本标注工具doccano遇到的报错以及解决方案 最近在用doccano搭标注平台的时候遇到了一些问题&#xff0c;总是报错&#xff0c;下面记录一下 pip install doccano首先检查python版本得是3.9,否则会报错 报错信息如下&#xff1a; ERROR: No matching distribution fou…

个人网厅——销户

目录 需求文档 公积金销户类 controller层 service层 service层实现类 1.验证 &#xff08;个人账户&#xff09; 2.提交&#xff08;添加&#xff09; controller层 service层 service层实现类 3.分页查询 controller层 service层 service层实现类 4. 详情查询…

知了汇智主题讲座走进四川轻化工大学

2011年&#xff0c;Netscape创始人马克安德森一句“软件正在吞噬世界”掀起热浪&#xff0c;随着云计算、大数据、人工智能等技术的日趋成熟&#xff0c;我们发现吞噬当下世界的是数字化技术&#xff0c;而非软件。 数字化技术一方面改变着国家、企业、个人之间的竞争规则&…

U-Mail邮件系统安全登录解决方案

企业邮箱是企业对内对外商务往来的主要通信工具&#xff0c;并且企业邮箱里面还包含了大量企业内部隐私信息、商业机密等&#xff0c;很容易成为黑客的攻击目标。其中邮件盗号是企业邮箱遭受攻击的主要形式&#xff0c;一旦企业邮箱密码被黑客盗取&#xff0c;黑客不仅可以利用…