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

一、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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机二级C语言的注意事项及相应真题-5-程序修改

目录 41.累加链表结点数据域中的数据作为函数值返回42.根据整型形参m&#xff0c;计算如下公式的值43.删除数列中值为x的元素44.从N个字符串中找出最长的那个串&#xff0c;并将其地址作为函数值返回45.将两个长度相等的纯数字字符串当作两个加数&#xff0c;求其代表的数值之和…

【Docker】Linux主机部署Docker

Docker部署 1.二进制文件部署 到如下地址&#xff0c;下载二进制包。 Docker官网&#xff1a;https://docs.docker.com/engine/install/binaries/ 网易镜像源&#xff1a;https://mirrors.163.com/docker-ce/linux/static/stable/x86_64/ 下载好的二进制包上传到主机&#xf…

C++项目 -- 高并发内存池(七)性能瓶颈与优化

C项目 – 高并发内存池&#xff08;七&#xff09;性能瓶颈与优化 文章目录 C项目 -- 高并发内存池&#xff08;七&#xff09;性能瓶颈与优化一、检测性能瓶颈二、使用基数树来优化项目1.基数树2.不加锁的原理3.性能对比 三、最终代码实现 一、检测性能瓶颈 DeBug下运行代码&…

015—pandas 标记按月连续变化趋势

前言 在业务数据分析中&#xff0c;特别是和时间相关的数据&#xff0c;会经常要判断数据的变化情况&#xff0c;比如是否是增长还是降低&#xff0c;或是持平。 需求 以数据中最后的月份为基础&#xff0c;来看它最近的数据变化&#xff0c;并将变化情况标记在本行的最后一…

网络基础与通信原理:构建数字世界的框架

目录 初识计算机网络 网络介绍 按照拓扑分类 按地域分类 网络设备 交换机&#xff08;switch&#xff09; 路由器&#xff08;router&#xff09; 传输介质 双绞线 光纤 光纤速度 ISO ISO和OSI有什么关系呢&#xff1f; OSI七层模型 TCP/IP四层 TCP/IP协议族 …

Atmel ATSHA204应用总结

1 ACES软件安装 Atmel Crypto Evaluation Studio (ACES) https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/Atmel%20Crypto%20%20Studio%20(ACES) 2 基本概念 ACES CE&#xff1a;Atmel Crypto Evalution Studio Configuration Environment&#xff08;基于加…

美国纽约时代广场纳斯达克大屏投放-大舍传媒

美国纽约时代广场纳斯达克大屏投放-大舍传媒 引言 对于大舍传媒来说&#xff0c;能够在美国纽约时代广场纳斯达克大屏投放广告是一个里程碑式的时刻。这不仅仅代表着大舍传媒在全球范围内的知名度与实力&#xff0c;也标志着该公司在国际市场上取得了巨大的进展。纽约时代广场…

Prometheus+TDengine集群实现监控体系高可用

背景 为避免再次出现因Prometheus宕机导致业务无法查看历史数据受到影响&#xff0c;准备将Prometheus架构从单节点方式升级为高可用集群方式并将后端存储由本地存储改为远端分布式时序数据库存储。分布式时序数据库采用国产数据库TDengine。 架构 解释&#xff1a;虚线代表P…

【安卓基础3】Activity(一)

&#x1f3c6;作者简介&#xff1a;|康有为| &#xff0c;大四在读&#xff0c;目前在小米安卓实习&#xff0c;毕业入职 &#x1f3c6;安卓学习资料推荐&#xff1a; 视频&#xff1a;b站搜动脑学院 视频链接 &#xff08;他们的视频后面一部分没再更新&#xff0c;看看前面也…

C#之WPF学习之路(1)

目录 WPF的起源 C的qt和C#的wpf对比 winform 和 wpf有什么区别 安装 Visual Studio2022 创建 HelloWorld 程序 App.xaml与Application类 Application的生命周期 Window窗体的生命周期 WPF的起源 WPF&#xff08;Windows Presentation Foundation&#xff09;是一种用于…

《图解设计模式》笔记(二)交给子类

三、Template Method模式&#xff1a;将具体处理交给子类 示例程序类图 public static void main(String[] args) {// 生成一个持有H的CharDisplay类的实例AbstractDisplay d1 new CharDisplay(H);// 生成一个持有"Hello, world."的StringDisplay类的实例AbstractD…

【HarmonyOS应用开发】三方库(二十)

三方库的基本使用 一、如何获取三方库 目前提供了两种途径获取开源三方库&#xff1a; 通过访问Gitee网站开源社区获取 在Gitee中&#xff0c;搜索OpenHarmony-TPC仓库&#xff0c;在tpc_resource中对三方库进行了资源汇总&#xff0c;可以供开发者参考。 通过OpenHarmony三…

数字世界的探索者:计算机相关专业电影精选推荐

目录 推荐计算机专业必看的几部电影 《黑客帝国》 《社交网络》 《乔布斯传》 《心灵捕手》 《源代码》 《盗梦空间》 《头号玩家》 《我是谁&#xff1a;没有绝对安全的系统》 《战争游戏》(WarGames) 《模仿游戏》(The Imitation Game) 《硅谷》(Silicon Valley) …

SpringBoot+WebSocket实现即时通讯(四)

前言 紧接着上文《SpringBootWebSocket实现即时通讯&#xff08;三&#xff09;》 本博客姊妹篇 SpringBootWebSocket实现即时通讯&#xff08;一&#xff09;SpringBootWebSocket实现即时通讯&#xff08;二&#xff09;SpringBootWebSocket实现即时通讯&#xff08;三&…

如何在Shopee 上选择热销商品?shopee应该在哪选品

在如今激烈竞争的电商市场中&#xff0c;如何通过精准的选品策略提升在Shopee平台上的销售业绩成为卖家们关注的焦点。Shopee作为一个蓬勃发展的电商平台&#xff0c;提供了多种资源和工具来帮助卖家做出明智的选品决策。通过深入了解这些渠道和策略&#xff0c;卖家们可以更好…

第2.4章 StarRocks表设计——分区分桶与副本数

目录 一、数据分布 1.1 概述 1.2 数据分布方式 1.2.1 Round-Robin 1.2.2 Range 1.2.3 List 1.2.4 Hash 1.3 StarRocks的数据分布方式 1.3.1 不分区 Hash分桶 1.3.2 Range分区Hash分桶 三、分区 3.1 分区概述 3.2 创建分区 3.2.1 手动创建分区 3.2.2 批量创建分区…

微服务篇之负载均衡

一、Ribbon负载均衡流程 二、Ribbon负载均衡策略 1. RoundRobinRule&#xff1a;简单轮询服务列表来选择服务器。 2. WeightedResponseTimeRule&#xff1a;按照权重来选择服务器&#xff0c;响应时间越长&#xff0c;权重越小。 3. RandomRule&#xff1a;随机选择一个可用的服…

Java 那些诗一般的 数据类型 (1)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

如何实现一个K8S DevicePlugin?

什么是device plugin k8s允许限制容器对资源的使用&#xff0c;比如CPU和内存&#xff0c;并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时&#xff0c;就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架&#xff0c;你可以用…

一文读懂函数式接口、Lambda表达式、Stream

文章目录 前言版本函数式接口定义特点使用 Lambda表达式主要场景用法无参写法有参写法 Lambda 表达式的基础&#xff1a;函数式接口 类型推断自定义函数接口使用 Lambda 表达式底层实现JDK7JDK8 this 的含义JDK7JDK8 Stream特点操作Stream 流创建中间操作和终端操中间操作无状…