C++ Primer 第八章 标准 IO 库

8.1. 面向对象的标准库

IO 类型在三个独立的头文件中定义:iostream 定义读写控制窗口的类型,fstream 定义读写已命名文件的类型,而 sstream 所定义的类型则用于读写存储在内存中的 string 对象。在 fstream 和 sstream 里定义的每种类型都是从 iostream 头文件中定义的相关类型派生而来。

 

 

Header

Type

iostream

istream 从流中读取

ostream 写到流中去

iostream 对流进行读写;从 istream 和 ostream 派生而来

fstream

ifstream 从文件中读取;由 istream 派生而来

ofstream 写到文件中去;由 ostream 派生而来

fstream 读写文件;由 iostream 派生而来

sstream

istringstream 从 string 对象中读取;由 istream 派生而来

ostringstream 写到 string 对象中去;由 ostream 派生而来

stringstream 对 string 对象进行读写;由 iostream 派生而来

 

迄今为止,所描述的流类(stream class)读写的是由 char 类型组成的流。此外,标准库还定义了一组相关的类型,支持 wchar_t 类型。每个类都加上“w ”前缀 ,以此与 char 类型的版本区分开来 。于是,wostream 、wistream 和 wiostream 类型从控制窗口读写 wchar_t 数据。相应的文件输入输出类是 wifstream 、wofstream 和 wfstream 。而 wchar_t 版本的 string 输入/输出流则是 wistringstream 、wostringstream 和 wstringstream 。标准库还定义了从标准输入输出读写宽字符的对象。这些对象加上“w ”前缀,以此与 char 类型版本区分:wchar_t 类型的标准输入对象是 wcin ;标准输出是 wcout ;而标准错误则是 wcerr 。

 

IO 对象不可复制或赋值

这个要求有两层特别重要的含义。正如在第九章 看到的,只有支持复制的元素类型可以存储在 vector 或其他容器类型里 。由于流对象不能复制 ,因此不能存储在 vector (或其他)容器中(即不存在存储流对象的 vector 或其他容器) 。

 

第二个含义是:形参或返回类型也不能为流类型 。如果需要传递或返回 IO 对象,则必须传递或返回指向该对象的指针或引用:

 

8.2. 条件状态

实现 IO 的继承正是错误发生的根源。一些错误是可恢复的;一些错误则发生在系统底层,位于程序可修正的范围之外。IO 标准库管理一系列条件状态(condition state) 成员,用来标记给定的 IO 对象是否处于可用状态 ,或者碰到了哪种特定的错误。表 8.2 列出了标准库定义的一组函数和标记,提供访问和操纵流状态的手段。

 

表 8.2. IO 标准库的条件状态

strm ::iostate

 

机器相关的整型名,由各个 iostream 类定义,用于定义条件状态

strm ::badbit

 

strm ::iostate 类型的值,用于指出被破坏的流

strm ::failbit

 

strm ::iostate 类型的值,用于指出失败的 IO 操作

strm ::eofbit

 

strm ::iostate 类型的值,用于指出流已经到达文件结束符

s.eof()

如果设置了流 s 的 eofbit 值,则该函数返回 true

s.fail()

如果设置了流 s 的 failbit 值,则该函数返回 true

s.bad()

如果设置了流 s 的 badbit 值,则该函数返回 true

s.good()

如果流 s 处于有效状态,则该函数返回 true

s.clear()

 

将流 s 中的所有状态值都重设为有效状态

s.clear(flag)

 

将流 s 中的某个指定条件状态设置为有效。flag 的类型是 strm ::iostate

s.setstate(flag)

 

给流 s 添加指定条件。flag 的类型是 strm ::iostate

s.rdstate()

 

返回流 s 的当前条件,返回值类型为 strm ::iostate

 

if 语句直接检查流的状态,而 while 语句则检测条件表达式返回的流,从而间接地检查了流的状态。如果成功输入,则条件检测为 true 。

 

    int ival;
    // read


 cin


 and test only for EOF; loop is executed even if there are other IO failures



    while (cin >> ival, !cin.eof()) {
        if (cin.bad())         // input stream is corrupted; bail out



            throw runtime_error("IO stream corrupted");
        if (cin.fail()) {                        // bad input



            cerr<< "bad data, try again";        // warn the user



            cin.clear(istream::failbit);         // reset the stream



            continue;                            // get next input



        }
        // ok to process


 ival



    }

8.3. 输出缓冲区的管理

系统将字符串字面值存储在与流 os 关联的缓冲区中。下面几种情况将导致缓冲区的内容被刷新,即写入到真实的输出设备或者文件:

程序正常结束 。作为 main 返回工作的一部分,将清空所有输出缓冲区。

在一些不确定的时候,缓冲区可能已经满了 ,在这种情况下,缓冲区将会在写下一个值之前刷新。

用操纵符(第 1.2.2 节 )显式地刷新缓冲区,例如行结束符 endl 。

在每次输出操作执行完后,用 unitbuf 操作符设置流的内部状态,从而清空缓冲区 。

可将输出流与输入流关联(tie )起来。在这种情况下,在读输入流时将刷新其关联的输出缓冲区 。

 

我们的程序已经使用过 endl 操纵符,用于输出一个换行符并刷新缓冲区。除此之外,C++ 语言还提供了另外两个类似的操纵符。第一个经常使用的 flush ,用于刷新流,但不在输出中添加任何字符。第二个则是比较少用的 ends ,这个操纵符在缓冲区中插入空字符 null,然后后刷新它:

 

如果需要刷新所有输出,最好使用 unitbuf 操纵符。这个操纵符在每次执行完写操作后都刷新流:

cout << unitbuf << "first" << " second" << nounitbuf;

等价于:

    cout << "first" << flush << " second" << flush;

nounitbuf 操纵符将流恢复为使用正常的、由系统管理的缓冲区刷新方式。

 

警告:如果程序崩溃了,则不会刷新缓冲区

如果需要使用最后的输出给程序错误定位,则必须确定所有要输出的都已经输出。为了确保用户看到程序实际上处理的所有输出, 最好的方法是保证所有的输出操作都显式地调用了 flush 或 endl 。

 

将输入和输出绑在一起

tie 函数可用 istream 或 ostream 对象调用,使用一个指向 ostream 对象的指针形参。调用 tie 函数时,将实参流绑在调用该函数的对象上。如果一个流调用 tie 函数将其本身绑在传递给 tie 的 ostream 实参对象上,则该流上的任何 IO 操作都会刷新实参所关联的缓冲区。

 

一个 ostream 对象每次只能与一个 istream 对象绑在一起 。如果在调用 tie 函数时传递实参 0,则打破该流上已存在的捆绑。

 

8.4. 文件的输入和输出

fstream 类型除了继承下来的行为外,还定义了两个自己的新操作—— open 和 close ,以及形参为要打开的文件名的构造函数。fstream 、ifstream 或 ofstream 对象可调用这些操作,而其他的 IO 类型则不能调用 。

 

警告:C++ 中的文件名

由于历史原因,IO 标准库使用 C 风格字符串(第 4.3 节 )而不是 C++ strings 类型的字符串作为文件名。在创建 fstream 对象时,如果调用 open 或使用文件名作初始化式,需要传递的实参应为 C 风格字符串,而不是标准库 strings 对象。程序常常从标准输入获得文件名。通常,比较好的方法是将文件名读入 string 对象,而不是 C 风格字符数组。假设要使用的文件名保存在 string 对象中,则可调用 c_str 成员(第 4.3.2 节 )获取 C 风格字符串。

检查文件打开是否成功

打开文件后,通常要检验打开是否成功,这是一个好习惯:

    // check that the


 open


 succeeded



    if (!infile) {
        cerr << "error: unable to open input file: "
             << ifile << endl;
        return -1;
    }
将文件流与新文件重新捆绑

先关再开 ,如:

     ifstream infile("in");      // opens file named "in" for reading



     infile.close();             // closes "in"



     infile.open("next");        // opens file named "next" for reading



清除文件流的状态

如果希望避免在每次 while 循环过程中创建新流对象,可将 input 的定义移到 while 之前。这点小小的改动意味着必须更仔细地管理流的状态。如果遇到文件结束符或其他错误,将设置流的内部状态,以便之后不允许再对该流做读写操作。关闭流并不能改变流对象的内部状态。如果最后的读写操作失败了,对象的状态将保持为错误模式,直到执行 clear 操作重新恢复流的状态为止。调用 clear 后,就像重新创建了该对象一样。

    ifstream input;
    vector<string>::const_iterator it = files.begin();
    //   for each file in the


 vector



    while (it != files.end()) {
        input.open(it->c_str());  // open the file



        // if the file is ok, read and "process" the input



        if (!input)
            break;                    // error: bail out!



        while(input >> s) // do the work on this file



            process(s);
        input.close();        // close file when we're done with it






        input.clear();        // reset state to ok






        ++it;                 // increment iterator to get next file



    }

如果程序员需要重用文件流读写多个文件,必须在读另一个文件之前调用 clear 清除该流的状态。

 

 

8.4.2. 文件模式

 

in

打开文件做读操作

out

打开文件做写操作

app

在每次写之前找到文件尾

ate

打开文件后立即将文件定位在文件尾

trunc

打开文件时清空已存在的文件流

binary

以二进制模式进行 IO 操作

 

 

从效果来看,为 ofstream 对象指定 out 模式等效于同时指定了 out 和 trunc 模式。


对同一个文件作输入和输出运算

fstream 对象既可以读也可以写它所关联的文件。fstream 如何使用它的文件取决于打开文件时指定的模式 。

默认情况下,fstream 对象以 in 和 out 模式同时打开。当文件同时以 in 和 out 打开时不清空。如果打开 fstream 所关联的文件时,只使用 out 模式,而不指定 in 模式,则文件会清空已存在的数据。如果打开文件时指定了 trunc 模式,则无论是否同时指定了 in 模式,文件同样会被清空。 下面的定义将 copyOut 文件同时以输入和输出的模式打开:

    // open for input and output



    fstream inOut("copyOut", fstream::in | fstream::out);
模式是文件的属性而不是流的属性

8.5. 字符串流

  • istringstream ,由 istream 派生而来,提供读 string 的功能。

  • ostringstream ,由 ostream 派生而来,提供写 string 的功能。

  • stringstream ,由 iostream 派生而来,提供读写 string 的功能。

表 8.5. stringstream 特定的操作

stringstream strm;

 

创建自由的 stringstream 对象

stringstream strm(s);

 

创建存储 s 的副本的 stringstream 对象,其中 s 是 string 类型的对象

strm.str()

 

返回 strm 中存储的 string 类型对象

strm.str(s)

 

将 string 类型的 s 复制给 strm ,返回 void

 

Android Audio基础——系统服务(二) AudioService 继承自 IAudioService.Stub。IAudioService.Stub 类很明显是通过 IAudioService.aidl 自动生成的。AudioService 位于 Binder Native 端。AudioManager 拥有 AudioService 的 Binder Proxy 端,是 AudioService 在客户端的一个代理。几乎所有客户端对 AudioManager 进行的请求,最终都会交由 AudioService 实现。 阅读详情

相关推荐

京东联盟API实战:5分钟搞定商品返利链接生成(附Python代码)

本文详细介绍了如何利用京东联盟API快速构建自动化商品返利链接生成系统。通过Python代码实战,从API申请、环境配置到核心功能封装,手把手教你实现批量商品信息查询与推广链接生成,帮助内容创作者和开发者大幅提升电商推广效率。

weixin_29216957的博客 674

C++ primer 标准IO库

要同时支持不同类型不同大小的字节流,标准库使用继承来定义一组面向对象类。通过继承关联起来的类型共享共同的接口。当一个类继承另一个类的时候这两个类可以使用相同的操作。 父类叫做基类,继承而来的叫派生类。 IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,sstream定义用于读写存储在内存中的string对象。 在fsteam和ss

xxiaozr的博客 388

本地使用大模型:Ollama+open-webui+AnythingLLM(Windows+linux)

随着大模型的发展,大量的开源模型可以被直接使用。大模型的使用可以选择在云端或者在本地,如果本地存储空间尚可,而且模型需求不是很大的话,我们可以选择在本地部署一个大模型来使用。针对特定的任务需求,进一步在本地去微调我们的大模型。我在windows和linux上都尝试了一遍,这里记录一下过程。

wpqgt的博客 2166

C++ PRIMER 第八章 标准IO库

  操纵符是一个函数或一个对象,会影响流的状态,并能用作输入或输出的运算符的运算对象(操作数)(a manipulator is a function or object that can be used as an operand to an input or outputoperator.) 第8章 标准IO库    8.1 面向对象的标准库   sstream所定义的类型用于读写存...

金色的省略号 160

实战:如何通过修改VTS和HTS调整GC4653 sensor帧率(附完整计算步骤)

本文以GC4653图像传感器为例,详细解析了通过修改VTS和HTS寄存器来精确调整输出帧率的完整流程。文章深入剖析了帧率计算公式FPS = PCLK / (VTS × HTS)的核心原理,并提供了从获取寄存器参数、计算目标VTS值到系统验证的实战步骤,帮助工程师掌握独立优化Sensor性能、提升低照度画质的关键技能。

gin88的博客 338

【PCB专题】Allegro导出3D文件

Allegro中如何导出3D文件,有没有一键导出操作?

一点硬件 4988

C++ Primer 4 第八章 标准 IO 库

第八章 标准 IO 库 1. 面向对象的标准库 IO 类型在三个独立的头文件中定义:iostream 定义读写控制窗口的类型,fstream 定义读写已命名文件的类型,而 sstream 所定义的类型则用于读写存储在内存中的 string 对象。在 fstream 和 sstream 里定义的每种类型都是从 iostream 头文件中定义的相关类型派生而来。istream 是 ifstream

我的读书笔记(2011-2013) 481

uniapp - [全端兼容] 详解实现国际化多语言切换全流程及示例,全部页面中英文多语言随意切换即时生效,语言切换全项目立即变化可自定义新增各国其他语言,uniApp实现中英文语言切换完整源码教程!

uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,uniapp多语言实现,uni-app项目使用多语言切换功能,中英文切换,uniapp实现中英文语言切换,uniApp实现国际化多语言切换,中文英文之间的更换,Uniapp使用什么插件能支持多种语言,退出后重启依然能让语言保留,设置可切换中英文,uniapp国际化页面双语/顶部导航双语/根据系统语言双语,标题栏文字原生底部菜单tabbar怎么改,使用vue-i18n国际化多国语言,全平台i18n插件,

🏆 前端领域优质创作者 1万+

C++ Primer第八章标准IO库笔记

IO对象不可复制或赋值 这有两个含义: 1)由于流对象不能复制,则不能存储在vector(或其它)容器中(即不存在存储流对象的vector或其它容器). 2)形参或返回类型不能为流类型,如果需要传递或者返回IO对象,则必须传递或返回指向该对象的指针或引用. ofstream out1, out2; // 错,不能赋值 out1 = out2; // 错,参数为流类型(调用的时候就会执行复制操作...

qq_26496077的博客 278

古风仙侠少女三视图提示词,一键生成角色设定

3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。平视正交视角,统一光照,纯白背景,无文字无水印,避免强透视和动态变形。3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。少女,古风仙侠少女气质,灵动、温婉、仙气。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 1059

创龙 瑞芯微 RK3588 国产2.4GHz八核 工业开发板—ISP图像处理开发案例

创龙科技研发的 TL3588-EVM 评估板具备强大视频处理能力,可满足多场景视频开发需求。为助力开发者快速上手,本文整理 7 个实用视频开发案例,涵盖从采集到显示的全流程,详细说明各案例的硬件连接、参数配置与代码解析,帮助开发者高效实现评估板视频相关功能开发与调试。

创龙,嵌入式一体化解决方案商 209

c++ primer读书笔记-第八章 标准IO库

c++ primer读书笔记-第八章 标准IO库前面的程序已经使用了多种 IO 标准库提供的工具: • istream(输入流)类型,提供输入操作。 • ostream(输出流)类型,提供输出操作。 • cin(发音为 see-in):读入标准输入的 istream 对象。 • cout(发音为 see-out):写到标准输出的 ostream 对象。 • c

梦想还是要有的 727

ABAP RAP 行为建模深入学习:从 Behavior Definition 到 Behavior Implementation 的完整实践指南

ABAP RAP开发指南:业务行为定义与实现 本文介绍SAP RAP框架中业务对象行为的开发方法: 分层设计 Behavior Definition声明业务能力(增删改查、校验、动作等) Behavior Implementation在ABAP类中编写具体逻辑 核心组件 使用BDL定义业务行为 通过FOR BEHAVIOR OF绑定行为池类(ABP) 在本地类实现校验/确定/动作逻辑 关键特性 支持managed/unmanaged两种实现模式 提供草稿表、并发控制等企业级功能 通过EML以别名访问实体 开

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 413

C++primer第八章标准io库

一、流状态查询和控制  int ival;  while(cin>>ival,!cin.eof())  {   if(cin.bad())   {    throw runtime_error("io stream corrupted");//runtime_error在stdexcept头文件中     }   if(cin.fail())   {    cerr    c

299

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【重学《C++Primer第四版》】第八章、标准IO库

本章主要讲解了IO标准库的基础知识。 下面是本章的内容图:简单的iostream继承层次 Details of knowledge 1.基类:C++中的父类就是基类 2.派生类:C++中继承(inheritance)而来的类称为派生类 3.输出缓冲区的4种刷新方式 cout cout相当于,cout cout cout 等价于cout 其中nounit

职场亮哥 698

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

C++Primer笔记 第八章 标准IO库

C++ 的输入/输出(input/output)由标准库提供。 标准库定义了一族类型,支持对文件和控制窗口等设备的读写(IO)。 还定义了其他一些类型,使 string对象能够像文件一样操作,从而使我们无须 IO 就能实现数据与字符之间的转换。 这些 IO 类型都定义了如何读写内置数据类型的值。 前面的程序已经使用了多种 IO 标准库提供的工具: ? istream(输入流)类型

北雨南萍 1364

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

(笔记)C++ Primer/第八章 标准IO库

IO:就是输入和输出 读和写 IO对象不可进行复制和赋值 例如:ofstream out1,out2;          out1=out2//error,io对象不能复制和赋值 如果一个函数需传递或返回IO对象,必须返回该对象的指针或引用.   IO条件状态 如果想在一次调用中设置或清除多个条件状态可以使用位或操作符 例如:is.setstate(ifstream::badb

u011760757的专栏 865

C++primer第4版第八章标准IO库

流不能复制。 ofstream o1, o2; o1 = o2; //wrong 流不能直接作为函数形参或者返回值,但可以使用流的引用或者指针

na_beginning的专栏 331

c++primer学习笔记 ( 第八章 标准IO库)

第八章 标准IO库 istream,ostream,cin,cout,cerr,>>,, getline函数,分别取istream和string类型的两个引用形参。 8.1面向对象的标准库 io标准库类型和头文件 iostream  fstream sstream io对象不可复制或赋值 8.2 条件状态 1、IO标准库内部的条件状态: 2、 strm::io

GinSmile的博客 1499

C++ Primer 第八章 标准IO库(转载)

学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章《C++编程对缓冲区的理解》,内容如下: 什么是缓冲区   缓冲区又称为缓存,它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。   缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。 ...

weixin_30415801的博客 106

【c++primer】第八章01——标准IO库

编写一个函数,其唯一的 //get.cpp //自定义的get实现文件、源文件 #include"stdafx.h" #include"get.hpp" // std::istream & get(std::istream & in) { int ival; while(in >> ival,!in.eof()) { if(in.bad())//如果出现系统故障,抛

蝉之洞 523

【C++ Primer】【学习笔记】【第八章】标准IO库之:条件状态

一、IO标准库的条件状态 操作 含义 stream::iostate 条件状态对应的类型名称。 stream::badbit stream::iostate类型的值,用于指出被破坏的流。 stream::failbit stream::iostate类型的值,用于指出失败的IO操作。

木名的专栏 620
上一篇: C++ Primer 第五版 读书笔记 第一章
下一篇: C++ Primer 第五版 读书笔记 第二章
techmonkey
博客等级 码龄14年 0粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值