C++格式化输入和输出

格式化输入与输出

除了条件状态外,每个iostream对象还维护一个格式状态来控制IO如何格式化的细节。

格式状态控制格式化的某些方面,如整型值是几进制、浮点值的精度、一个输出元素的宽度等。

标准库定义了一组操纵符来修改流的格式状态。

一个操纵符是一个函数或是一个对象,会影响流的状态,并能用作输入或输出运算符的运算对象。类似输入和输出运算符,操纵符也返回它所处理的流对象,因此我们可以在一条语句中组合操纵符和数据。

我们已经在程序中使用过一个操纵符——endl,我们将它“写”到输出流,就像它是一个值一样。但endl不是一个普通值,而是一个操作:它输出一个换行符并刷新缓冲区。

很多操纵符改变格式状态

操纵符用于两大类输出控制;控制数值的输出形式以及控制补白的数量和位置。

大多数改变格式状态的操纵符都是设置/复原成对的;

一个操纵符用来将格式状态设置为一个新值,而另一个用来将其复原,恢复为正常的默认格式。

当操纵符改变流的格式状态时,通常改变后的状态对所有后续IO都生效

当我们有一组IO操作希望使用相同的格式时,操纵符对格式状态的改变是持久的这特性很有用。

实际上,一些程序会利用操纵符的这一特性对其所有输入或输出重置一个成多个格式规则的行为。在这种情况下,操纵符会改变流这一特性就是满足要求的了。

但是,很多程序(而且更重要的是,很多程序员)期望流的状态符合标准库正常的默认设置。在这些情况下,将流的状态置于一个非标准状态可能会导致错误。因此,通常最好在不再需要特殊格式时尽快将流恢复到默认状态。

控制整型格式

控制布尔值的格式

操纵符改变对象的格式状态的一个例子是 boolalpha 操纵符。

默认情况下,bool值打印为1或0。一个true值输出为整数1,而false输出为0,我们可以通过对流使用booialpha操纵符来覆盖这种格式:

cout << "default bool values: " << true << " " << false;
cout<< "\nalpha bool values: " << boolalpha<< true << " " << false << endl;


执行这段程序会得到下面的结果:

default bool values: 1 0
alpha bool values: true false

一旦向cout“写入”了boolalpha,我们就改变了cout打印bool值的方式。后续打印bool值的操作都会打印true或false而非1或0。

为了取消cout格式状态的改变,我们使用noboolalpha:

cout << boolalpha //设置cout的内部状态<< true << endl<< noboolalpha//将内部状态恢复为默认格式<< true << endl;



指定整型值的进制

默认情况下,整型值的输入输出使用十进制。

我们可以使用操纵符hex、oct和dec将其改为十六进制、八进制或是改回十进制:

cout << "default: " << 20 << " " << 1024 << endl;
cout << "octal: " << oct << 20 << " " << 1024 << endl;
cout << "hex: " << hex << 20 << " " << 1024 << endl;
cout << "decimal: " << dec << 20 << " " << 1024 << endl;

当编译并执行这段程序时,会得到如下输出:

注意,类似boolalpha,这些操纵符也会改变格式状态。它们会影响下一个和随后所有的整型输出,直至另一个操纵符又改变了格式为止。

操纵符hex、oct和dec只影响整型运算对象,浮点值的表示形式不受影响

在输出中指出进制

默认情况下,当我们打印出数值时,没有可见的线索指出使用的是几进制。

例如,20是十进制的20还是16的八进制表示?

当我们按十进制打印数值时,打印结果会符合我们的期望。

如果需要打印八进制值或十六进制值,应该使用showbase 操纵符。

当对流应用showbase 操纵符时,会在输出结果中显示进制,它遵循与整型常量中指定进制相同的规范:

  1. 前导0x表示十六进制。
  2. 前导0表示八进制。
  3. 无前导字符串表示十进制。

我们可以使用showbase修改前一个程序:

cout << showbase;// 当打印整型值时显示进制cout << "default: " << 20 << "    " << 1024 << endl;
cout << "in octal: " << oct << 20 << "   " << 1024 << endl;
cout << "in hex: " << hex << 20 << "   " << 1024 << endl;
cout << "indecimal: " << dec << 20 << "   " << 1024 << endl;cout << noshowbase; //恢复流状态


修改后的程序的输出会更清楚地表明底层值到底是什么:

操纵符noshowbase恢复cout的状态,从而不再显示整型值的进制。

默认情况下,十六进制值会以小写打印,前导字符也是小写的x。我们可以通过使用uppercase操纵符来输出大写的X并将十六进制数字a-f以大写输出:

cout << uppercase << showbase << hex
<< "printed in hexadecimal: " << 20 << " " << 1024
<<nouppercase << noshowbase << dec << endl;


这条语句生成如下输出:

printed in hexadecimal; 0X14 0X400


我们使用了操纵符nouppercase、noshowbase和dec来重置流的状态。

控制浮点数格式

我们可以控制浮点数输出三个种格式:

  1. 以多高精度(多少个数字)打印浮点值
  2. 数值是打印为十六进制,定点十进制还是科学记数法形式
  3. 对于没有小数部分的浮点值是否打印小数点

默认情况下,浮点值按六位数字精度打印;

cout << 3.1111111111 << endl;

 

如果浮点值没有小数部分,则不打印小数点。

cout << 3.0000000000 << endl;

根据浮点数的值选择打印成定点十进制或科学记数法形式。

标准库会选择一种可读性更好的格式:非常大和非常小的值打印为科学记数法形式,其他值打印为定点十进制形式。

指定打印精度

默认情况下,精度会控制打印的数字的总数。

当打印时,浮点值按当前精度舍入而非截断。

因此,如果当前精度为四位数字,则3.14159将打印为3.142,如果精度为三位数字,则打印为3,14。
 

我们可以通过调用IO对象的precision成员或使用setprecision操纵符来改变精度。

precision成员是重载的。

  1. 一个版本接受一个int值,将精度设置为此值,并返回旧精度值。
  2. 另一个版本不接受参数,返回当前精度值。

setprecision操纵符接受一个参数,用来设置精度。

操纵符 setprecision和其他接受参数的操纵符都定义在头文件 iomanip中。

下面的程序展示了控制浮点值打印精度的不同方法:

// cout.precision返回当前精度值cout << "Precision: " << cout.precision()<< ", Value:" << sqrt(2.0) << endl;// cout.precision(12)将打印精度设置为12住数字cout.precision(12);cout << "Precision:" << cout.precision()<< ", Value:" << sqrt (2.0) << endl;// 另一种设置精度的方法是使用setprecision操纵符cout << setprecision(3);cout << "Precision:" << cout.precision()<< ", Value:" << sqrt(2.0) << endl;


编译并执行这段程序,会得到如下输出:

此程序调用标准库sqrt函数,它定义在头文件cmath中。

sqrt函数是重载的,不同版本分别接受一个float、double或long double参数,返回实参的平方根。

定义在iostream的操纵符
注意:*表示默认流状态
boolalpha将true和false输出为字符串
* noboolalpha将true和false输出为1,0
showbase对整型值输出表示进制的前缀
* noshowbase不生成表示进制的前缀
showpoint对浮点值总是显示小数点
*noshowpoint只有当浮点值包含小数部分时才显示小数点
showpos对非负数显示+
*noshowpos对非负数不显示+
uppercase在十六进制值中打印0X,在科学记数法中打印E
*nouppercase在十六进制值中打印0x, 在科学记数法中打印e
*dec整型值显示为十进制
hex整型值显示为十六进制
oct整型值显示为八进制
left在值的右侧添加填充字符
right在值的左侧添加填充字符
lnternal在符号和值之间添加填充字符
fixed浮点值显示为定点十进制
scientific浮点值显示为科学记数法
hexfloat浮点值显示为十六进制(C++11新特性)
defaultfloat重置浮点数格式为十进制(C++11新特性)
unitbuf每次输出操作后都刷新缓冲区
*nounitbuf恢复正常的缓冲区刷新方式
*skipws输入运算符跳过空白符
noskipws输入运算符不跳过空白符
flush刷新ostream缓冲区
ends插入空字符,然后刷新ostream缓冲区
endl插入换行,然后刷新ostream缓冲区

指定浮点数记数法

除非你需要控制浮点数的表示形式(如,按列打印数据或打印表示金额或百分比的数据),否则由标准库选择记数法是最好的方式。

通过使用恰当的操纵符,我们可以强制一个流使用科学记数法、定点十进制或是十六进制记数法。

  • 操纵符scientific改变流的状态来使用科学记数法。
  • 操纵符fixed改变流的状态来使用定点十进制。
  • 在新标准库中,通过使用hexfloat 也可以强制浮点数使用十六进制格式。
  • 新标准库还提供另一个名为defaultfloat的操纵符,它将流恢复到默认状态——根据要打印的值选择记数法。

这些操纵符也会改变流的精度的默认含义。

在执行 scientific、fixed或hexfloat后,精度值控制的是小数点后面的数字位数,而默认情况下精度值指定的是数字的总位数——既包括小数点之后的数字也包括小数点之前的数字。

使用fixed或scientific令我们可以按列打印数值,因为小数点距小数部分的距离是固定的:

cout << "default format: " << 100 * sqrt(2.0) << '\n'<< "scientific: " << scientific << 100 * sqrt(2.0) << '\n'<< "fixed decimal: " << fixed << 100 * sqrt(2.0) << '\n'<< "hexadecimal: " << hexfloat << 100 * sqrt(2.0) << '\n'<< "use defaults: " << defaultfloat << 100 * sqrt(2.0);


此程序会生成下面的输出:

默认情况下,十六进制数字和科学记数法中的e都打印成小写形式,我们可以用uppercase操纵符打印这些字母的大写形式。

打印小数点

强制打印小数点:
默认情况下,当一个浮点值的小数部分为0时,不显示小数点。showpoint 操纵符

cout << 10.0 << endl;// 打印10
cout << showpoint << 10.0 //打印10.0000
<< noshowpoint << endl; //恢复小数点的默认格式

操纵符noshowpoint恢复默认行为。下一个输出表达式将有默认行为,即,当浮点值的小数部分为0时不输出小数点。

输出补白

当按列打印数据时,我们常常需要非常精细地控制数据格式。

标准库提供了一些操纵符帮助我们完成所需的控制:

  1. setw指定下一个数字或字符串值的最小空间。
  2. left表示左对齐输出。
  3. right表示右对齐输出,右对齐是默认格式。
  4. internal控制负数的符号的位置,它左对齐符号,右对齐值,用空格填满所有中间空间。
  5. setfill允许指定一个字符代替默认的空格来补白输出。

setw类似endl,不改变输出流的内部状态。它只决定下一个输出的大小。
下面程序展示了如何使用这些操纵符:

	int i = -16;double d = 3.14159;//补白第一列,使用输出中最小12个位置cout << "i:" << setw(12) << i << "next col" << '\n'<< "d: " << setw(12) << d << "next col" << '\n';//补白第一列,左对齐所有列cout << left<< "i: " << setw(12) << i << "next col" << '\n'<< "d: " << setw(12) << d << "next col" << '\n'<< right; //恢复正常对齐//补白第一列,右对齐所有列cout << right<< "i: " << setw(12) << i << "next col" << '\n'<< "d: " << setw(12) << d << "next col" << '\n';//补白第一列,但补在域的内部cout << internal<< "i:" << setw(12)<< i << "next col" << '\n'<< "d: " << setw(12)<< d << "next col" << '\n';//补白第一列,用#作为补白字符 符。cout << setfill('#')<< "i: " << setw(12) << 1 << "next col" << '\n'<< "d: " << setw(12) << d << "next col" << '\n'<< setfill(' ');//恢复正常的补白字符

执行这段程序,会得到下面的输出:

定义在iomanip的操作符
setfill(ch)用ch填充空白
setprecision(n)将浮点精度设置为n
setw(w)读或写值的宽度为w个字符
setbase(b)将整数输出为b进制


控制输入格式

默认情况下,输入运算符会忽略空白符(空格符、制表符、换行符、换纸符和回车符)。

下面的循环

char ch;
while (cin >> ch)
cout << ch;


当给定下面输入序列时

a b         c
d

循环会执行4次,读取字符a到d,跳过中间的空格以及可能的制表符和换行符。

此程序的输出是

abcd

操纵符 noskipws会令输入运算符读取空白符,而不是跳过它们。为了恢复默认行为,我们可以使用skipws操纵符:

cin >> noskipws;// 设置cin 读取空白符
while (cin >> ch)
cout << ch;
cin >> skipws; //将cin恢复到默认状态,从而丢弃空白符


给定与前一个程序相同的输入,此循环会执行7次,从输入中既读取普通字符又读取空白符。此循环的输出为

a b        c
d


 

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

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

相关文章

电商系列之商详

> 插&#xff1a;AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

java解数独(力扣Leetcode37)

数独问题 力扣原题链接 问题描述 数独的解法需遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 数独部分空格内已填入了数字&#xff0c;空白格用.表示。 示例 示例&…

微服务监控:确保分布式系统的可观察性与稳定性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 一、前言二、微服务监控的重要性三、关键监控指标四、常用监控工具五、最佳实践六、结论 一、前言 在当前的软件开发领域&a…

const在指针中的作用以及*p在各种写法中分别代表什么含义

const在指针中起固定的作用&#xff0c;在不同的写法中其效果也有所区别&#xff0c;具体如下&#xff1a; 1、int* const p固定的是指针p指向的地址。 2、int const *p固定的是指针p指向地址中储存的内容。 例&#xff1a; 以上操作在编译器中执行不了&#xff0c;会报错。…

项目中预览图片时,添加水印,浏览器禁止右键功能、前端禁止直接获取图片地址。(Vue3、TS、canvas)

在src/utils文件夹下新建watermark.ts&#xff0c;写入以下代码块&#xff0c;生成水印文件 // 导出函数 getWatermark&#xff0c;它返回一个对象&#xff0c;其中包含一个名为 watermark 的方法。 export const getWatermark () > {const setWatermark (str: any) >…

Java基础知识总结(29)

Java虚拟机 运行时数据区 程序计数器 方法区&#xff1a;Java 8以后没有方法区&#xff0c;改为了元空间&#xff08;MetaSpace&#xff09; 虚拟机栈 堆 本地方法栈 程序计数器 它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里&#xff0c…

flutter生成二维码并截图保存到图库

引入库&#xff1a;flutter_screenutil、image_gallery_saver、qr_flutter弹窗布局 import dart:async; import dart:typed_data; import package/generated/l10n.dart; import package:jade/configs/PathConfig.dart; import package:jade/utils/ImageWaterMarkUtil.dart; im…

瑞吉外卖实战学习--8、人员禁用和启用

前言 1、通过前端页面查看接口 会发现请求方式是put 请求接口是employee 2、检查页面传值 根据浏览器的请求可以看到传值为id和status 2、写put请求&#xff0c;添加修改时间和修改人的id然后传回给后台 /*** 启用和禁用员工账号* param request* param employee* return…

【Consul】Linux安装Consul保姆级教程

【Consul】Linux安装Consul保姆级教程 大家好 我是寸铁&#x1f44a; 总结了一篇【Consul】Linux安装Consul保姆级教程✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 今天要把编写的go程序放到linux上进行测试Consul服务注册与发现&#xff0c;那怎么样才能实现这一过程&am…

25Ramdisk 启动模式简介

Ramdisk 启动模式简介 ramdisk是一种虚拟磁盘技术,我们的PE系统几乎都是使用ramdisk方式从计算机启动的.那么,ramdisk有哪些特点呢? Ramdisk 将内存虚拟为一个磁盘 Ramdisk技术会将你的一部分内存虚拟成一块磁盘分区.使用U盘启动pe系统时,打开pe系统里的文件资源管理器,你会看…

CKS之安全沙箱运行容器:gVisor

目录 一、gVisor介绍 二、gVisor架构 三、gVisor使用前置条件 四、Docker中使用gVisor 五、containerd中使用gVisor 六、Kubernetes结合gVisor使用 一、gVisor介绍 gVisor是Google开源的一种容器沙箱技术&#xff0c;其设计初衷是在提供较高安全性的同时&#xff0c;尽量…

Stable Diffusion 推荐硬件配置和本地化布署

Stable Diffusion简介 Stable Diffusion是由Stability AI开发的一种强大的文本到图像(Text-to-Image)生成模型,它能够根据用户提供的文本描述,生成与之相关的高质量、高分辨率图像。下面我从原理、特点、应用三个方面对Stable Diffusion作简要介绍: 1、原理:Stable Diffusion…

从输入url到页面展示的过程

唠唠叨&#xff1a;我不想误人子弟&#xff0c;我这篇算是搬运工&#xff0c;加上自己的理解做点总结&#xff0c;所以还请大家科学上网去看这篇&#xff1a;https://aws.amazon.com/cn/blogs/mobile/what-happens-when-you-type-a-url-into-your-browser/ 是这六个步骤&#…

杰发科技——Jlink插件使用

0. 简介 杰发自带的烧录工具是ATCLink&#xff0c;基于DapLink适配。个人不太喜欢ATCLink&#xff0c;推荐使用Jlink&#xff0c;毕竟自己买&#xff0c;不用问原厂要&#xff0c;而且带Jlink&#xff0c;至少5Mhz以上。 V9烧录器使用7.50以下版本驱动。 V11烧录器可以使用7…

热烈祝贺阿里云PolarDB登顶2024最新一期中国数据库流行榜

热烈祝贺阿里云PolarDB登顶2024最新一期中国数据库流行榜 墨天轮墨天轮国产数据库流行度排行PolarDB首度夺魁关于话题的讨论数据库流行度排行榜会影响你的数据库选型吗&#xff1f;对于 PolarDB 的本次登顶&#xff0c;你认为关键因素是什么&#xff1f;PolarDB“三层分离”新版…

【Review】小米汽车发布会

动力方面 顶配双电机四驱&#xff0c;小米超级电机21000转&#xff0c;最大马力673ps&#xff0c;峰值功率495kW&#xff0c;峰值扭矩838N.m。风阻系数最低0.195&#xff0c;零百加速最快2.78秒&#xff0c;时速最高265km/h。 底盘方面 前双叉臂&#xff0c;后无五连杆&#xf…

springcloud第4季 远程调用openfegin的介绍4

一 openfegin的介绍 1.1 openfegin的介绍 openfegin是一个声明式的web客户端&#xff1b;只需要创建一个rest接口并在该接口上添加注解FeginClient即可。openfeign基本上就是当前微服务之间调用的事实标准。 openfeign同时还集成了sprigcloud loadbalance。

01-XML-01认识XML

XML 被设计出来用于数据的记录和传递&#xff0c;经常被作用为配置文件 什么是XML 可扩展标记语言&#xff08;Extensible Markup Language&#xff09;,没有固定的标签&#xff0c;所有的标签都可以自定义。使用简单的标记来描述数据通常&#xff0c;xml被用于信息的记录和传…

An Interview

What is your experience with Python and MySQL? Can you provide examples of projects you have worked on using these technologies? How would you handle customer requirements gathering and analysis? Can you provide an example of how you have translated cu…

C++—vector的介绍及使用 vector的模拟实现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、vector的介绍及使用 1.1 vector的介绍 1.2 vector的使用 1.2.1 vector的定义 1.2.2 vector iterator 的使用 1.2.3 vector 空间增长问题 1.2.4 vecto…