C++:输入流/输出流

C++流类库简介

C++为了克服C语言中的scanfprintf存在的缺点。,使用cin/cout控制输入/输出。

  1. cin:表示标准输入的istream类对象,cin从终端读入数据。
  2. cout:表示标准输出的ostream类对象,cout向终端写数据。
  3. cerr:表示标准错误输出(非缓冲方式),导出程序错误信息。
  4. clog:表示标准错误输出(缓冲方式),导出程序错误信息。

为了在程序中使用cin/cout,必须在程序中包含iostream库的相关头文件,格式为:#include <iostream>
iostream类同时从istream(输入流)和ostream(输出流)类派生出来,允许双向输入/输出。输入由重载的>>运算符完成,输出由重载的<<运算符完成,输入/输出格式为:cin>>变量名/cout<<变量名
除了用户端的输入/输出,C++还提供了文件的输入/输出类:

  1. ifstream:从istream派生而来,把文件绑定到程序上输入。
  2. ofstream:从ostream派生而来,把文件绑定到程序上输出。
  3. fstream:从iostream派生而来,把文件绑定到程序上输入/输出。

使用iostream库的文件流,必须包含相关的头文件:#include <fstream>
常用的流类库层次结构如图所示:
在这里插入图片描述

ios类作为流类库的基类,主要派生了istream、ostream类,由这两个类又派生了很多使用的流类,除ifstream类、ofstream类、iostream类外,还有strstream(输入/输出串流类)、istrstream(输入串流类)、ostrstream(输出串流类)等。下面将对这些流类的作用及用法分别进行介绍。

输入流/输出流格式

基本输出流

C++的ostream提供了丰富的格式化和误格式化的输出功能:用流插入运算符输出标准数据类型;put库成员函数输出字符;以八进制、十进制、十六进制数的形式输出数据;以各种精确方式输出浮点型数据;以科学计数法定点输出数据等。
流输出考研用流插入运算符,即重载的<<(左移位)运算符来完成。<<运算符左边的操作数时istream类的一个对象(如cout),右边可以是C++的合法表达式。
C++还提供了指针预定义输出运算符,允许输出项为显示对象的地址。在默认情况下,地址以十六进制的形式显示。

基本输入流

对应于输出,C++提供了实用的输入功能。类似于输出流中的流插入运算符,输入中引入了流读取运算符,也称为提取运算符。
流输入可以用流读取运算符,即重载的>>(右移位)运算符来完成。类似于<<运算符,流读取运算符是双目运算符,左边的操作数是istream类的一个对象(如cin),右边的操作数是系统定义的任何数据类型的变量
注意:1. >>运算符也支持级联输入。在默认情况下,>>运算符会跳过空格,读入后面与变量类型相应的值。因此,给一组变量输入值时,要用空格或换行符将输入的数值间隔开。
2. 当输入字符串时,>>运算符会跳过空格,读入后面的非空格符,直到遇到另外一个空格才结束,并在字符串末尾自动放置字符\0作为结束标志。
3. 输入数据时,不仅检查数据间的空格,还要进行类型检查、自动匹配

格式化输入/输出

在很多情况下,用户希望自己控制输出格式。C++提供了两种格式控制方法:用ios类成员函数控制格式和用操纵符控制格式。

1. ios类成员函数控制格式

ios类中,格式控制函数主要是通过对状态标志字、域宽、填充字及其精度来完成的。输入/输出格式由一个long int型的状态标志字确定。在ios类中public部分进行了枚举,见下表:

状态标志作用
skipws跳过输入中的空白
left左对齐格式输出
right右对齐格式输出
internal在符号位和数值之间填入字符
dec十进制数显示
oct八进制数显示
hex十六进制数显示
showbase产生前缀,指示数值的进制基数
showpoint总是显示小数
uppercase十六进制数显示0X,科学计数法显示E
showpos在非负数中显示“+
boolalphatruefalse表示为字符串
scientific以科学记数法形式显示浮点数
fixed以小数形式显示浮点数
unitbuf输出操作后立即刷新所有流
stdio输出操作后刷新stdoutstderr
  1. 设置状态标志
    设置状态标志可使用long ios::setf(long flags)函数,格式为:stream_obj.setf(ios::enum_type);
    说明:其中,stream_obj为被影响的流对象,常用的是cincoutenum_type为上表中列举的值。要想设置多个状态,彼此间用运算符“|”连接(不能连接相反的格式控制符)。
  2. 清除状态标志
    清除状态标志可使用long ios::unsetf(long flags),格式为:stream_obj.unsetf(ios::enum_type);使用方法和ios::setf()相同。
  3. 取状态标志
    取状态标志用flags(),在ios类中重载了两个版本,格式为:long ios::flags();long ios::flags(long flag);前者用于返回当前状态标志字;后者将状态标志字存储在flag内。需要注意的是,与setf()设置状态标志字不同,flags()是取状态标志字的。
  4. 设置域宽
    域宽用于控制输出格式,在ios类中重载了两个函数控制域宽,原型为:int ios::width();或者 int ios::width(int w);第一个函数得到当前的域宽了第二个函数用来设置新的域宽,并返回原来的域宽。需要注意的是,所设置的域宽仅仅对下一个输出的操作有效,当完成一次输出操作后,域宽又恢复为0
  5. 设置填充字符
    填充字符的作用是,当输出值不满域宽时用设定的字符来填充,默认填充的字符为空字符。实际应用中填充字符函数与设置域宽函数配合使用,否则无空可填,毫无意义。ios类提供了两个重载的成员函数来操作填充字符,原型为:char ios::fill();或者char ios::fill(char c);第一个函数返回当前使用的填充字符;第二个函数设置新的填充字符,并返回设置前的填充字符。
  6. 设置显示精度
    类似地,ios类也提供了重载的两个函数来显示精度,原型为:int ios::precision();或者int ios::precision(int num);第一个函数返回当前数值精度值;第二个函数设置新的显示精度,并返回设置前的精度。

2.操纵符控制格式

使用ios类成员函数控制输入/输出格式,必须靠流对象来调用,而且不能直接嵌入输入/输出语句中,使用不够方便。C++提供了另外一种控制格式的方法,称为操纵符(控制符)方法,类似于函数的运算符。使用操纵符方法可以嵌入输入/输出语句中。
所有不带参数的操纵符定义在头文件iosream.h中,带形参的操纵符定义在头文件iomanip.h中,使用操纵符时需要包含相应的头文件。
提供的操纵符如下便:

标志作 用
ws在输入时跳过开头的空白符,仅用于输入
endl换行并刷输出流,仅用于输出
ends插入一个空字符,仅用于输出
flush刷新一个输出流,仅用于输出
skipws在输入时跳过输入中的空白符,仅用于输入
noskipws在输入时不跳过输入中的空白符,仅用于输入
internal将填充字符加到符号和数值之间
dec十进制数显示,可用于输入/输出
oct八进制数显示,可用于输入/输出
hex十六进制数显示,可用于输入/输出
showbase产生前缀,指示数值的进制基数
noshowbase不产生基数前缀
showpoint总是显示小数
noshowpoint只有当小数存在时显示小数
uppercase十六进制数显示0X,科学计数法显示E
nouppercase十六进制数显示0x,科学计数法显示e
showpos在非负数中显示“+
noshowpos在非负数中不显示“+
boolalphatruefalse表示为字符串
noboolalphatruefalse表示为1和0
scientific以科学记数法形式显示浮点数
fixed以小数形式显示浮点数
setfill(ch)ch填充空白字符
setprecision(n)将浮点数精度设置为n
setw(w)按照w个字符来读或写数值
setbase(b)以进制基数b来输出整数值
setiosflags(n)设置有n指定的格式标志
resetiosflags(n)清除有n指定的格式标志

用户自定义的操纵符控制格式

在C++中,除系统提供的预定义操纵符之外,还允许用户定义操纵符,便于控制一些频繁使用的格式操作,使格式控制更加方便。
自定义输出流操纵符算子函数格式为:ostream &自定义输出操纵符算子函数名(ostream& stream){return stream;}
自定义输入流操纵符算子函数格式为:istream &自定义输出操纵符算子函数名(istream& stream){return stream;}

其他输入/输出函数

  1. get()put()
    get(char& ch)从输入流中提取一个字符,包括空白字符,并把它存储在ch中,返回被应用的istream对象。此函数在类istream里。
    对应于get(),类ostream提供了put(char ch),用于输出字符。
    gei()的重载版本:get(char *str, streamsize size,char delimiter='\n');
    其中str代表一个字符数组,用来存放被读取的字符。size代表可以从istream中读入字符的最大数目。delimiter代表如果遇到它就要结束读取字符的动作,delimiter本身不会被读入,而是留在istream中,作为istream的下一个字符。常见的一个错误是,执行第二个get()时省略delimiter
  2. getline()
    使用get()输入字符串时,经常忘记去掉delimiter所以引入函数getline(),其原型和get()的重载一样:getline(char *str, streamsize size,char delimiter='\n');
    使用getline()get()方便,它除去了delimiter,而不是将其留作下一个字符。
  3. write()read()
    ostream类成员函数write()提供一种输出字符数组的方法。它不是输出“直到终止字符为止”,而是输出某个长度的字符序列,包括空字符。函数原型如下:write(char *str, streamsize size);
    其中str是要输出的字符数组,length是要显示的字符个数。write()返回当前被调用的ostream类对象。
    ostream类的write()对应的是istream类的read(),原型如下:read(char *str, streamsize size);
    read()从输入流中读取size个连续的字符,并将其放在地址从str开始的内存中。gcount()返回由最会一个read()调用所读取的字节数,而read()返回当前被调用的istream类对象。

用户自定义类型的输入/输出

当实现一个类的类型时,有时需要这个类支持输入和输出的操作,以便可以将类对象嵌入输入或输出流中。对于用户自定义的数据类型的输入/输出,可以通过重载>>运算符和<<运算符实现。

重载输出运算符

输出运算符<<,又称为流插入运算符。定义其重载函数的格式为:

ostream &operator<<(ostream &out, class_name &obj)
{
	out << obj.data1;
	out << obj.data2;
	```
	return out;
}

函数中第一个参数out是对ostream对象的引用,即out必须是输出流对象;第二个参数是用户自定义要输出的类对象的引用。
<<运算符不能作为类的成员函数,只能作为友元函数(要访问类的私有成员)来实现。

重载输入运算符

输入运算符>>,又称为流提取运算符。定义其重载函数的格式为:

istream &operator<<(istream &in, class_name &obj)
{
	in >> obj.data1;
	in >> obj.data2;
	```
	return in;
}

函数中第一个参数in是对istream对象的引用,即in必须是输入流对象;第二个参数是用户自定义要输入的类对象的引用。
<<运算符类似,>>运算符也不能作为类的成员函数,只能作为类的友元函数或独立函数。
例如:>>运算符和<<运算符重载

#include <iostream>
#include <string>
using namespace std;
class Word
{
	char* word;
	size_t iNum;//存储字符个数
public:
	Word(const char* const str = NULL);
	virtual ~Word()
	{
		if (word)
			delete[]word;
	}
	friend ostream& operator <<(ostream& out, const Word& obj);
	friend istream& operator >>(istream& in, Word& obj);
};

Word::Word(const char* const str)
{
	if (str != NULL)
	{
		iNum = strlen(str);
		word = new char[iNum + 1];
		strcpy_s(word, iNum + 1, str);
	}
}

ostream& operator<<(ostream& out,const Word& obj)
{
	out << "<" << obj.iNum << ">" << obj.word << endl;
	return out;
}

istream& operator>>(istream& in, Word& obj)
{
	char str[100];
	in.getline(str, 100);
	if (in.gcount() > 0)
	{
		delete[]obj.word;
		obj.iNum = strlen(str);
		obj.word = new char[obj.iNum + 1];
		strcpy_s(obj.word, obj.iNum + 1, str);
	}
	return in;
}

int main()
{
	Word word("hello");
	cout << word;
	cin >> word;
	cout << word;
	return 0;
}

程序运行结果为:

<5>hello
W
<1>W

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

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

相关文章

如何远程操控vm虚拟机(finalshell版)

你是否因为虚拟机命令行操作不便而头疼&#xff1f;是否因为难以复制粘贴而烦恼&#xff1f;是否因为无法快速上传文件而烦躁&#xff1f; 别急&#xff01;现在有一个简单便捷的软件能够实现上述你所述说的所有烦恼&#xff0c;请听我细细道来~ 一、查看虚拟机的ip地址 a.首…

Unity C#高级特性 Partial 详细使用案例

文章目录 实例 1&#xff1a;分隔UI逻辑实例 2&#xff1a;Unity编辑器自动生成代码实例 3&#xff1a;数据模型分割实例 4&#xff1a;序列化扩展实例 5&#xff1a;多视图架构实例 6&#xff1a;Unity编辑器自定义 inspectors 在Unity中&#xff0c;部分类&#xff08;Partia…

Java多线程--生产者与消费者问题

文章目录 一、生产者与消费者问题&#xff08;1&#xff09;概要&#xff08;2&#xff09;案例1、案例描述及需要明确的问题2、整体框架构思3、生产者和消费者的数据共享问题4、对Clerk类里面方法的设计5、测试6、唤醒机制7、两个消费者 二、是否释放锁的操作&#xff08;1&am…

PMP备考的三个阶段及学习方法分享

PMP证书是项目管理必备的关键技能证书&#xff0c;是具备进行项目管理的重要技能体现。无论升职加薪&#xff0c;还是从事项目管理工作&#xff0c;都非常重要。 个人主要从事产品开发工作&#xff0c;开始逐渐承担一些项目经理角色&#xff0c;但目前项目管理知识薄弱&#x…

探讨深浅拷贝在js加密中的运用

深浅拷贝是JavaScript中常用的概念&#xff0c;用于复制对象或数组。它们在处理数据时有不同的用途&#xff0c;适用于不同的场景。在本文中&#xff0c;我们将详细介绍深浅拷贝的概念&#xff0c;提供案例代码&#xff0c;并探讨它们在JavaScript中的应用场景&#xff0c;以及…

@JsonFormat 和 @@DateTimeFormat 时间格式化注解详解(一篇带你解决问题)

前后数据交互过程中&#xff0c;Date类型的数据经常会出现类型映射转换的错误&#xff0c;为了达到业务的目标时间格式&#xff0c;通常会使用JsonFormat 和 DateTimeFormat&#xff0c;但是这两者有什么区别呢&#xff1f; 一、示例代码 先准备一个POJO&#xff0c;拥有Date类…

PPT录屏功能在哪?一键快速找到它!

在现代办公环境中&#xff0c;ppt的录屏功能日益受到关注&#xff0c;它不仅能帮助我们记录演示文稿的播放过程&#xff0c;还能将操作过程、游戏等内容完美录制下来。可是很多人不知道ppt录屏功能在哪&#xff0c;本文将为您介绍ppt录屏的打开方法&#xff0c;以帮助读者更好地…

本体论(ontology)在工业4.0中的应用

信息技术中的本体与哲学的本体论是不同的&#xff0c;它代表了某个专业领域的基本概念&#xff0c;它们在智能制造和工业4.0 中具有不可或缺的作用&#xff0c;为了实现人与机器&#xff0c;机器与机器之间的确定性操作。一个标准化的&#xff0c;精确定义的本体服务是非常重要…

【XR806开发板试用】xr806使用tcp socket与手机通信

本文为极术社区XR806开发板活动试用文章。 参考&#xff1a;基于星辰处理器的全志XR806开源鸿蒙开发板上手体验 搭建环境。并成功编译。 项目源码 &#xff1a; https://gitee.com/kingwho/smart-home 在同一个局域网中&#xff0c;手机与xr806连接后&#xff0c;手机 APP 每隔…

【开源】JAVA+Vue+SpringBoot实现就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

【对象属性拷贝】⭐️按照需要转换的类型反射设置拷贝后对象的属性

背景&#xff1a; 小伙伴们大家好&#xff0c;最近开发的时候遇到一种情况&#xff0c;项目引入了全局序列化器来实现Date&#xff0c;LocalDateTime类型的字段根据时区转换&#xff0c;总体来说接口没什么要改动的&#xff0c;只要原来字段的属性是以上两种就行&#xff0c;但…

Linux/Uinx 系统编程:进程管理(3)

Linux/Uinx 系统编程&#xff1a;进程管理&#xff08;3&#xff09; 本章来讲解进程管理的最后一部分内容。 文章目录 Linux/Uinx 系统编程&#xff1a;进程管理&#xff08;3&#xff09;I/O重定向原理FILE结构体的内部结构重定向的实现过程 scanf 与 printfscanfprintf 重定…

linux 组建和卸载raid1、raid0详细操作

组raid的最好是相同容量和型号的硬盘&#xff0c;否则会有木桶效应 linux下组raid有很多细节 一、安装raid软件 deb包 apt-get install mdadm或dnf包 dnf install mdadm二、组raid1-镜像&#xff0c;组raid0-并列 raid1和raid0只有在madam命令时一点点不同&#xff0c;其他…

了解野指针与assert断言 拿捏指针的使用!

目录 1.野指针 野指针的成因&#xff1a; 2.规避野指针 3.assert断言 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免费的赞哟~ 1.野指针 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的…

重写Sylar基于协程的服务器(5、IO协程调度模块的设计)

重写Sylar基于协程的服务器&#xff08;5、IO协程调度模块的设计&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器&#xff08;1、…

【论文阅读笔记】Taming Transformers for High-Resolution Image Synthesis

Taming Transformers for High-Resolution Image Synthesis 记录前置知识AbstractIntroductionRelated WorkMethodLearning an Effective Codebook of Image Constituents for Use in TransformersLearning the Composition of Images with Transformers条件合成合成高分辨率图…

阿狸与小兔子的奇幻之旅

在很久很久以前&#xff0c;有一个遥远的国度&#xff0c;这个国度里生活着各种各样的动物&#xff0c;它们和谐共处&#xff0c;幸福快乐。在这个国度里&#xff0c;有一只聪明伶俐的小狐狸&#xff0c;名叫阿狸。 一天&#xff0c;阿狸在森林里散步时&#xff0c;遇到了一只正…

【BIAI】Lecture10 - Motor System2

Motor System2 专业术语 descending spinal tracts 下行脊髓束 corticospinal tract 锥体束 reticulospinal tract 脊髓脑干束 vestibulospinal tract 脊髓脑干侧脊束 precentral gyrus 前中央回 population coding 群体编码 basal ganglia 基底节 thalamus 丘脑 Posterior pa…

Python中容器类型的数据

目录 序列 序列的索引操作 加和乘操作 切片操作 成员测试 列表 创建列表 追加元素 插入元素 替换元素 删除元素 元组 创建元组 元组拆包 集合 创建集合 修改集合 字典 创建字典 修改字典 访问字典视图 遍历字典 若我们想将多个数据打包并且统一管理&…

计算斐波那契数

前提需备知识&#xff1a; 斐波那契数列是第一项和第二项为1&#xff0c;第三项为前两项之和&#xff0c;然后以此类推的一个数列&#xff0c;即1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;8&#xff0c;13&#xff0c;21&#xff0c;34&#xff0c;5…