C++从入门到精通 第十二章(C++流)

 写在前面:

  1. 本系列专栏主要介绍C++的相关知识,思路以下面的参考链接教程为主,大部分笔记也出自该教程,笔者的原创部分主要在示例代码的注释部分。
  2. 除了参考下面的链接教程以外,笔者还参考了其它的一些C++教材(比如计算机二级教材和C语言教材),笔者认为重要的部分大多都会用粗体标注(未被标注出的部分可能全是重点,可根据相关部分的示例代码量和注释量判断,或者根据实际经验判断)。
  3. 如有错漏欢迎指出。

参考教程:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili

一、C++流的概念

1、C++流的体系结构

(1)C++为实现数据的输入输出定义了一系列的流类,这些类之间的派生、继承关系如下图所示,它们之中一部分是用模板实现的,图中用细线框表示,另外图中的虚线表示模板类与模板实例的关系。

(2)要利用C++流,必须在程序中包含有关的头文件,以便获得相关流类的声明。与C++流有关的头文件有:

①iostream:使用cin、cout等预定义流对象针对标准设备进行I/O操作。

②fstream:使用文件流对象针对磁盘文件进行I/O操作。

③ststream:使用字符串流对象针对内存字符串空间进行I/O操作。

④iomanip:使用setw、fixed等操作符进行格式控制。

2、预定义流对象

C++流有4个预定义流对象,它们的名称及与之联系的I/O设备如下,其中cin为istream类对象,其余3个为ostream类对象。

cin

标准输入

cout

标准输出

cerr

标准出错信息输出

clog

带缓冲的标准出错信息输出

3、提取运算符“>>”和插入运算符“<<”

(1)输入流类istream重载了运算符“>>”用于数据输入,其原型为

        istream& operator>>(istream&, <类型>&);

重载的“>>”的功能是从输入流中提取数据赋值给一个变量,因此称之为提取运算符。当系统执行cin>>x操作时,将根据实参x的类型调用相应的提取运算符重载函数,把x的引用传送给对应的形参,接着从键盘的输入缓冲区读入一个值并赋给x后,返回istream流,以便继续使用提取运算符为下一个变量输入数据。

(2)输出流类ostream重载了运算符“<<”用于数据输出,其原型为

        ostream& operator<<(ostream&, const <类型>&);

重载的“<<”的功能是把表达式的值插入到输出流中,因此称之为插入运算符。当系统执行cout<<x操作时,首先根据x的类型调用相应的插入运算符重载函数,把x的值传送给对应的形参,接着执行函数体,把x的值输出到显示器屏幕上,在当前屏幕光标位置显示,然后返回ostream流,以便继续使用插入运算符输出下一个表达式的值。

(3)除了可以将“>>”和“<<”运算符作用于C++中固有的数据类型外,还可以将其作为非成员函数重载作用于用户自定义类型,详见第十章——运算符重载,这里不再赘述。

4、有格式输入输出和无格式输入输出

利用C++流既可以进行有格式输入输出,也可以进行无格式输入输出。

(1)有格式输入输出针对的是键盘、显示器、打印机等字符设备以及磁盘中的文本文件,cin、cout等预定义流对象只能用于有格式输入输出,提取运算符和插入运算符也只能用于有格式输入输出。

(2)无格式输入输出只针对磁盘文件,需调用流对象中专门的成员函数实现。

二、输入输出的格式控制

1、默认的输入输出格式

(1)C++流所识别的输入数据类型及其默认的输入格式如下所示。

short、int、long(signed、unsigned)

与整型常量同

float、double、long double

与浮点数常量同

char(signed、unsigned)

第一个非空白字符

char * (signed、unsigned)

从第一个非空白字符开始到下一个空白字符结束

void *

无前缀的16进制数

bool

把true或1识别成true,其它均识别为false(VC6.0中把0识别为false,其它均识别为true)

(2)C++所识别的输出数据的类型及其默认的输出格式如下所示。

short、int、long(signed、unsigned)

一般整数形式,负数前有负号

float、double、long double

浮点格式或指数形式(科学计数法),较短者优先

char(signed、unsigned)

单个字符(无引号)

char * (signed、unsigned)

字符序列(无引号)

void *

无前缀的16进制数

bool

1或0

2、格式标志与格式控制

(1)在作为流库根类的ios_base中,有一个作为数据成员的格式控制变量专门用来记录格式标志,通过设置标志可以有意识地对有格式输入输出的效果加以控制。

(2)各种格式标志被定义为一组符号常量,如下表所示。

格式控制标志

含义

skipws

输入时跳过空白字符

left

输出数据在指定宽度内左对齐

right

输出数据在指定宽度内右对齐

internal

输出数据在指定宽度内内部对齐,即符号在最左端,数值数据右对齐

dec

整数按十进制输出

oct

整数按八进制输出

hex

整数按十六进制输出

showbase

显示数制标志

showpoint

浮点数即使小数部分为0也显示小数点,如114.0输出为114.000

uppercase

用大写字符输出数制标志

showpos

正数也显示符号

scientific

按指数格式(科学计数法)显示浮点数

fixed

按定点格式显示浮点数

unitbuf

每次输出操作后立即写缓

boolalpha

把逻辑值输出为true和false

3、输入输出宽度的控制

(1)宽度设置用于输入时只对字符串有效,宽度设置用于输出时指最小输出宽度。

(2)当实际数据宽度小于指定的宽度时,多余的位置用填充字符(通常是空格)填满;当实际数据的宽度大于设置的宽度时,仍按实际的宽度输出;初始宽度值为0,其含义是所有数据都按实际宽度输出。

(3)与宽度设置有关的操作符是“setw(int n)”,等价函数调用为“io.width(n)”,其中n为一个表示宽度的表达式,如果用于字符串输入,实际输入的字符串的最大长度为n-1,也就是说宽度n连字符串结束符也包含在内。函数width返回此前设置的宽度。

(4)宽度设置的效果只对一次输入或输出有效,在完成了一个数据的输入或输出后,宽度设置自动恢复为0。

4、浮点数输出方式的控制

(1)在初始状态下,浮点数按浮点格式输出,输出精度是指有效的个数,小数点的相对位置随数据的不同而浮动;将浮点数改变为按定点格式或指数格式(科学计数法)输出时,输出精度是指小数位数,小数点的相对位置固定不变,必要时进行舍入处理或添加无效0。

(2)浮点数输出方式的设置一直有效,直到再次设置浮点数输出方式时为止。

(3)与浮点数输出方式控制有关的操作符如下。

操作符

等价函数调用

输出方式

restiosflags(ios_base::floatfield)

o.unsetf(ios_base::floatfield)

浮点数按浮点格式输出(默认设置)

fixed

o.setf(ios_base::fixed, ios_base::floatfield)

浮点数按定点格式输出

scientific

o.setf(ios_base::scientific, ios_base::floatfield)

浮点数按指数格式输出

5、输出精度的控制

(1)输入输出精度是针对浮点数设置的,其实际含义与浮点数输出方式有关:

①如果采用浮点格式,精度的函数是有效位数。

②如果采用定点格式或指数格式,精度的含义是小数位数。

(2)精度的设置用于输出,默认值为6,可以通过设置改变精度,将精度值设置为0意味着回到默认精度6。

(3)精度值的设置一直有效,直到再次设置精度时为止。

(4)与精度设置有关的操作符为“setprecision(int n)”,等价函数调用为“io.precision(n)”,其中n为表明精度值的表达式。函数precision返回此前设置的精度。

6、对齐方式的控制

(1)初始的对齐方式为右对齐,可以改变这一设置,使得输出采用左对齐方式或内部对齐方式。

(2)对齐方式的设置一直有效,直到再次设置对齐方式为止。

(3)只有在设置了宽度的情况下,对齐操作才有意义。

(4)与对齐方式控制有关的操作符如下。

操作符

等价函数调用

输出方式

left

o.setf(ios_base::left, ios_base::adjustfield)

在设定的宽度内左对齐输出,右端使用设定的填充字符填满

right

o.setf(ios_base::right, ios_base::adjustfield)

在设定的宽度内右对齐输出,左端使用设定的填充字符填满(默认设置)

internal

o.setf(ios_base::internal, ios_base::adjustfield)

在设定的宽度内右对齐输出,但若有符号(-或+),则符号置于最左端

7、小数点处理方式的控制

(1)此设置只影响采用浮点格式输出的浮点数据。

(2)在初始状态下,若一浮点数的小数部分为0,则不输出小数点及小数点后的无效0,可以改变这一设置,使得在任何情况下都输出小数点及其后面的无效0。

(3)小数点处理方式的设置一直有效,直到再次设置小数点处理方式为止。

(4)与小数点处理方式控制有关的操作符如下。

操作符

等价函数调用

输出方式

showpoint

o.setf(ios_base::showpoint)

即使小数部分为0,也输出小数点及其后的无效0

noshowpoint

o.unsetf(ios_base::showpoint)

小数部分为0时不输出小数点(默认设置)

8、填充字符的控制

(1)在输出数据时,如果数据宽度小于设置的宽度,则空闲位置要用填充字符填满。

(2)初始填充字符为空格,可以将别的字符设置为填充字符。

(3)填充字符的设置一直有效,直到再次设置填充字符时为止。

(4)只有在设置了宽度的情况下,字符填充操作才有意义。

(5)与填充字符控制有关的操作符为“setfill(char c)”,等价函数调用为“io.fill(c)”,其中c是用于填充的字符。函数fill返回此前设置的填充字符。

9、插入换行符

(1)“endl”的作用是插入换行符,即插入’\n’,并强制写缓冲区,实现输出的回车换行。

(2)“endl”的等价函数调用为“o.put(o.widen(‘\n’)); o.flush()”。

10、输入输出数制状态的控制

(1)初始状态为十进制,可以将之设置为八进制或十六进制。

(2)数制状态的设置一直有效,直到下一次设置为止。

(3)与输入输出数制状态控制有关的操作符如下。

操作符

等价函数调用

输出方式

dec

io.setf(ios_base::dec, ios_base::basefield)

将整数按十进制输入输出(默认设置)

oct

io.setf(ios_base::oct, ios_base::basefield)

将整数按八进制输入输出

hex

io.setf(ios_base::hex, ios_base::basefield)

将整数按十六进制输入输出

setbase(int base)

io.setf(ios_base::oct, ios_base::basefield)等

设置数制(8、10、16)

showbase

o.setf(ios_base::showbase)

为输出的整数生成一个前缀,用以表示该数的数制(对于八进制数,前面输出一个无效0;对于十六进制数,前面输出“0x”)

noshowbase

o.unsetf(ios_base::showbase)

取消上述设置(默认设置)

uppercase

o.setf(ios_base::uppercase)

将数制标志中的字母以大写形式输出

nouppercase

o.unsetf(ios_base::uppercase)

数制标志中的字母恢复为小写形式(默认设置)

三、文件流

1、概述

(1)程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放,通过文件可以将数据持久化

(2)C++中对文件操作需要包含头文件 < fstream >

(3)文件类型分为两种:

文本文件——文件以文本的ASCII码形式存储在计算机中。

二进制文件——文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们。

(4)文件流以磁盘文件以及其它可按文件方式进行管理的外部设备作为输入输出对象,ifstream是文件输入流类(负责文件的读操作),ofstream是文件输出流类(负责文件的写操作),fstream是文件输入输出流类(负责文件的读写操作)。

(5)文件的打开方式:

利用|操作符可以实现文件打开方式配合使用,例如用二进制方式写文件:

        ios::binary |  ios:: out

2、写文件(文本文件)

(1)写文件步骤如下:

①包含头文件:

        #include <fstream>

②创建流对象:

        ofstream ofs;

③打开文件:

        ofs.open("<文件路径>", <打开方式>);

④写数据:

        ofs << "<写入的数据>";

⑤关闭文件:

        ofs.close();

(2)举例:

#include<iostream>
using namespace std;
#include<fstream>     //包含头文件void test01()
{ofstream ofs;   //创建流对象ofs.open("test.txt",ios::out);   //指定打开方式ofs << "姓名:张三" << endl;     //写内容ofs << "性别:男" << endl;ofs << "年龄:18" << endl;ofs.close();    //关闭文件
}int main() {test01();system("pause");return 0;
}

3、读文件(文本文件)

(1)读文件步骤如下:

①包含头文件:

        #include <fstream>

②创建流对象:

        ifstream ifs;

③打开文件并判断文件是否打开成功:

        ifs.open("<文件路径>", <打开方式>);

④读数据:

        //共有四种方式读取数据,具体见下例

⑤关闭文件

        ifs.close();

(2)举例:

#include<iostream>
using namespace std;
#include<fstream>     //包含头文件
#include<string>void test01()
{ifstream ifs;   //创建流对象ifs.open("test.txt",ios::in);   //指定打开方式if (!ifs.is_open()){cout << "文件打开失败" << endl;return;}char buf[1024] = { 0 };      //读取文件的第一种方式while (ifs >> buf){cout << buf << endl;}/*char buf[1024] = { 0 };    //读取文件的第二种方式while (ifs.getline(buf, sizeof(buf))){cout << buf << endl;}*//*string buf;                //读取文件的第三种方式while (getline(ifs, buf)){cout << buf << endl;}*//*char c;                    //读取文件的第四种方式(不推荐)while ( (c = ifs.get()) != EOF ){cout << buf << endl;}*/ifs.close();    //关闭文件
}int main() {test01();system("pause");return 0;
}

4、写文件(二进制文件)

(1)以二进制方式写文件主要利用流对象调用成员函数write,文件输出流对象可以通过write函数,以二进制方式写数据。

(2)write函数的原型:

        ostream& write(const char * buffer, int len);

        //字符指针buffer指向内存中一段存储空间,len是读写的字节数

(3)举例:

#include<iostream>
using namespace std;
#include<fstream>     //包含头文件class Person
{
public:char m_Name[64];int m_Age;
};void test01()
{ofstream ofs;   //创建流对象ofs.open("person.txt", ios::out | ios::binary);   //指定打开方式//ofstream ofs("person.txt", ios::out | ios::binary);  上两句可以合并Person p = { "张三",18 };ofs.write((const char *)&p,sizeof(Person));     //写文件ofs.close();    //关闭文件
}int main() {test01();system("pause");return 0;
}

5、读文件(二进制文件)

(1)二进制方式读文件主要利用流对象调用成员函数read,文件输入流对象可以通过read函数,以二进制方式读数据。

(2)read函数的原型:

        istream& read(char *buffer,int len);

        //字符指针buffer指向内存中一段存储空间,len是读写的字节数

(3)举例:

#include<iostream>
using namespace std;
#include<fstream>     //包含头文件class Person
{
public:char m_Name[64];int m_Age;
};void test01()
{ifstream ifs;   //创建流对象ifs.open("person.txt", ios::in | ios::binary);   //指定打开方式if (!ifs.is_open()){cout << "文件打开失败" << endl;return;}Person p;           //读文件ifs.read((char *)&p, sizeof(Person));cout << "姓名:" << p.m_Name << " 年龄:" << p.m_Age << endl;ifs.close();    //关闭文件
}int main() {test01();system("pause");return 0;
}

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

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

相关文章

Vue 图片轮播第三方库 介绍

Vue图片轮播是一种在网页上以自动或手动方式展示图片的组件&#xff0c;常用于产品展示、网站banner等场景。有许多第三方库可以帮助Vue开发者轻松实现图片轮播功能。以下是一些流行的Vue图片轮播第三方库的介绍&#xff1a; 1. Vue-awesome-swiper - **简介**&#xff1a;V…

滚雪球学Java(70):深入理解Java中的PriorityQueue底层实现与源码分析

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

Linux之ACL权限管理

文章目录 1.ACL权限介绍二、操作步骤1. 添加测试目录、用户、组&#xff0c;并将用户添加到组2. 修改目录的所有者和所属组3. 设定权限4. 为临时用户分配权限5. 验证acl权限6. 控制组的acl权限 1.ACL权限介绍 每个项目成员有一个自己的项目目录&#xff0c;对自己的目录有完全…

【Django】Django自定义后台表单——对一个关联外键对象同时添加多个内容

以官方文档为例&#xff1a; 一个投票问题包含多个选项&#xff0c;基本的表单设计只能一个选项一个选项添加&#xff0c;效率较低&#xff0c;如何在表单设计中一次性添加多个关联选项&#xff1f; 示例代码&#xff1a; from django.contrib import adminfrom .models impo…

森林安全新保障:智能高压应急消防泵的应用

随着城市化进程的加快&#xff0c;森林资源的保护和利用日益受到重视。然而&#xff0c;森林火灾时有发生&#xff0c;给生态环境带来严重破坏。为了有效应对森林火灾&#xff0c;保障森林资源安全&#xff0c;智能高压森林应急消防泵应运而生&#xff0c;成为守护绿色生命的钢…

Python列表:灵活多变的数据结构

文章目录 一、列表1.创建列表2.访问列表元素3.修改列表元素4.添加元素5.删除元素 二、列表脚本操作符1.连接运算符 2.重复运算符 * 三、列表函数&方法1.函数1.1 len() 函数1.2 max() 函数1.3 min() 函数1.4 sum() 函数1.5 list() 函数 2.方法2.1 append() 方法2.2 extend()…

DSL Query基本语法

DSL Query基本语法 查询的基本语法如下&#xff1a; GET /indexName/_search {"query":{"查询类型":{"查询条件":"条件值"}} }查询所有 GET /indexName/_search {"query":{"match_all":{}} }match查询&#xf…

2、Web攻防-SQL注入-联合查询注入

用途&#xff1a;个人学习笔记&#xff0c;有所借鉴&#xff0c;欢迎指正&#xff01; 声明&#xff1a;只用于学习交流&#xff0c;点到为止&#xff0c;请勿非法测试。 概念&#xff1a; 联合查询注入&#xff1a;联合注入是回显注入的一种&#xff0c;也就是说联合注入的前…

Gemma模型论文详解(附源码)

原文链接&#xff1a;Gemma模型论文详解&#xff08;附源码&#xff09; 1. 背景介绍 Gemma模型是在2023.2.21号Google新发布的大语言模型, Gemma复用了Gemini相同的技术(Gemini也是Google发布的多模态模型)&#xff0c;Gemma这次发布了了2B和7B两个版本的参数&#xff0c;不…

嵌入式Linux中apt、apt-get命令用法汇总

在Linux环境开发过程中接触ubuntu虚拟机时&#xff0c;在安装软件或者更新软件时apt和apt-get命令使用相对较频繁&#xff0c;下面对这两个命令的用法进行汇总。 apt&#xff08;Advanced Package Tool&#xff09;和 apt-get 是用于在基于 Debian 的 Linux 发行版中进行软件包…

什么是favicon.ico图标?如何在线生成ICO图标?如何安装favicon.ico图标?

在本站首页的活跃博客中经常看到有部分博客网站没有 favicon.ico 图标&#xff0c;所以今天打算普及一下相关知识&#xff0c;希望还没有 favicon.ico 图标的博主们&#xff0c;能够制作出自己独特的图标。 那么到底什么是favicon.ico&#xff1f; 好搜百科给出的解释&#xf…

electron学习和新建窗口

首先我们要先下载electron npm install --save-dev electron 建立入口文件main.js 新建一个入口文件 main.js&#xff0c;然后导入eletron新建一个窗口。 const { app, BrowserWindow, ipcMain } require("electron"); const path require("path");func…

Nginx 反向代理配置

Nginx就不废话了&#xff0c;web服务器。 最近在备案一个域名&#xff0c;想要备案&#xff0c;部署一个服务器&#xff0c;平常很少自己配置Nginx&#xff0c;今天记录下。 1、反向代理 正向代理 指 客户端通过代理访问后端服务 反向代理 指 服务器推出一个客户&#xff0…

6.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-通过逆向分析确定游戏明文发送数据过程

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;测试需求与需求拆解 在开始之前要了解一个小知识&#xff0c;在逆向开始之前要很清楚知道要找的东西是什么&#xff0c;大概长什么样子&#xff0c;只有这样才能看到它第一眼发现它&#xff0c;现在我…

Unable to make field private JavacProcessingEnvironment$DiscoveredPro报错解决办法

maven项目打包报错 报错信息 Unable to make field private com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors com.sun.tools.javac.processing.JavacProcessingEnvironment.discoveredProcs accessible: module jdk.compiler does not &q…

[论文精读]Do Transformers Really Perform Bad for Graph Representation?

论文网址&#xff1a;[2106.05234] Do Transformers Really Perform Bad for Graph Representation? (arxiv.org) 论文代码&#xff1a;https://github.com/Microsoft/Graphormer 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼…

springmvc+ssm+springboot房屋中介服务平台的设计与实现 i174z

本论文拟采用计算机技术设计并开发的房屋中介服务平台&#xff0c;主要是为用户提供服务。使得用户可以在系统上查看房屋出租、房屋出售、房屋求购、房屋求租&#xff0c;管理员对信息进行统一管理&#xff0c;与此同时可以筛选出符合的信息&#xff0c;给笔者提供更符合实际的…

PYQT5-自定义事件

from PyQt5.QtCore import QEvent, QObject from PyQt5.QtWidgets import QApplication import sys# 自定义事件类 class CustomEvent(QEvent):# PYQT5 预留给用户自定义事件类型的起点为 QEvent.User1000custom_event_type QEvent.registerEventType()# 也可以这样写# custom…

Python 实现 ADTM 指标计算:股票技术分析的利器系列(9)

Python 实现 ADTM 指标计算&#xff1a;股票技术分析的利器系列&#xff08;9&#xff09; 介绍算法解释 核心代码rolling函数介绍计算 DTMnp.where 使用介绍np.maximum 计算 DBM计算 STM计算 SBM计算 ADTM 完整代码 介绍 ADTM&#xff08;动态买卖气指标&#xff09;是一种用…

高级语言期末2012级B卷

1.编写函数&#xff0c;输出任意正整数n的位数&#xff08;n默认为存储十进制的整形变量&#xff09; 例如&#xff1a;正整数13&#xff0c;则输出2,&#xff1b;正整数3088&#xff0c;则输出4 #include <stdio.h>int func(int n) {int count0;while(n>0) {n/10;co…