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


 

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

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

相关文章

Vue3+.NET6前后端分离式管理后台实战(十)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战&#xff08;十&#xff09;已经在订阅号发布有兴趣的可以关注一下&#xff01; 感兴趣请关注订阅号谢谢&#xff01; 代码已经上传gitee

树莓派串口读取陀螺仪ky9250(mpu9250)数据

9轴姿态角度传感器&#xff0c;其中ky9250陀螺仪由于自带卡尔曼动态滤波算法方便用户使用。ky9250陀螺仪基本可以在各个平台上进行数据的读取&#xff08;如stm32\arduino\C#\Matlab\树莓\Unity3d\python\ROS\英飞凌\Nvidia jetson linux 等&#xff09; 1、树莓派和ky9250的接…

储能系统--BMS系统中的高压BUCK电路

一、Buck关键器件介绍 1、芯片选型 控制方式分类 优势缺点同步 1&#xff1a;效率高 2&#xff1a;MOS压降低 1&#xff1a;成本高 2&#xff1a;下官驱动复杂 异步 1&#xff1a;成本便宜 2&#xff1a;适合较高的输出电压 1&#xff1a;效率低 按照隔离方式分类 隔离电源…

会员制医疗预约服务管理信息系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 1. 系统功能…

基于Givens旋转完成QR分解进而求解实矩阵的逆矩阵

基于Givens旋转完成QR分解进而求解实矩阵的逆矩阵 目录 前言 一、Givens旋转简介 二、Givens旋转解释 三、Givens旋转进行QR分解 四、Givens旋转进行QR分解数值计算例子 五、求逆矩阵 六、MATLAB仿真 七、参考资料 总结 前言 在进行QR分解时&#xff0c;HouseHolder变换…

python基础——文件操作【文件编码、文件的打开与关闭操作、文件读写操作】

&#x1f4dd;前言&#xff1a; 这篇文章主要讲解一下python中对于文件的基础操作&#xff1a; 1&#xff0c;文件编码 2&#xff0c;文件的打开与关闭操作 3&#xff0c;文件读写操作 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;C语言入…

docker centos7在线安装Nginx

目录 1.在线安装Nginx2.配置开机启动 1.在线安装Nginx # 安装Nginx yum install epel-release yum install nginx2.配置开机启动 # 启动Nginx systemctl start nginx # 开机自启 systemctl enable nginx一般docker内的centos7安装Nginx的目录结构是&#xff1a; /etc/nginx为…

蓝桥杯第七届大学B组详解

目录 1.煤球数量&#xff1b; 2.生日蜡烛&#xff1b; 3.凑算式 4.方格填数 5.四平方和 6.交换瓶子 7.最大比例 1.煤球数量 题目解析&#xff1a;可以根据题目的意思&#xff0c;找到规律。 1 *- 1个 2 *** 3个 3 ****** 6个 4 ********** 10个 不难发现 第…

教培机构办公管理系统B端实战项目作品集Figma源文件

这是一套教培机构办公管理系统设计复盘作品集&#xff0c;都提供分层源文件 交付文件&#xff1a;设计复盘作品集源文件作品集里面的B端设计项目包装样机字体文件 交付格式&#xff1a;figma 作品集文件页数&#xff1a;19页 B端项目文件页数&#xff1a;15页 B端项目源文…

linux文件系统:VFS

文章目录 vfs1 super_block2 dentry2.1 dentry树2.2 dentry的cache2.3 挂载 3 inode4 文件file5 vfs各结构体的关系 vfs Linux内核通过虚拟文件系统&#xff08;Virtual File System&#xff0c;VFS&#xff09;管理文件系统 VFS为所有的文件系统提供了统一的接口&#xff0c…

算法沉淀——动态规划篇(子数组系列问题(上))

算法沉淀——动态规划篇&#xff08;子数组系列问题&#xff08;上&#xff09;&#xff09; 前言一、最大子数组和二、环形子数组的最大和三、乘积最大子数组四、乘积为正数的最长子数组长度 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都…

Available platform plugins are: linuxfb, minimal, offscreen, vnc.

说明&#xff1a; buildroots根文件中已经移植好了QT的库&#xff0c;但是运行QT交叉编译之后的可执行文件报错&#xff1a; qt.qpa.plugin: Could not find the Qt platform plugin "eglfs" in "" This application failed to start because no Qt platf…

P4995 跳跳!(贪心)

多么痛的领悟&#xff01;大数据要开long long&#xff01;&#xff01;&#xff01;简单longlong就AC&#xff01; 代码1&#xff1a; #include<algorithm> #include<iostream> #include<cstring> #include<queue> #include<cmath> using name…

哪种排序算法在不同情况下性能最好?

哪种排序算法在不同情况下性能最好&#xff1f;&#x1f50d;&#x1f4ca; 哪种排序算法在不同情况下性能最好&#xff1f;&#x1f50d;&#x1f4ca;&#x1f4dd; 摘要&#x1f680; 引言&#x1f4cb; 正文内容&#xff08;详细介绍&#xff09;冒泡排序快速排序&#x1f…

基于ssm旅游资源网站(java项目+文档+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的旅游资源网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 旅游资源网站的主要使用者分为管理…

RK3588平台开发系列讲解(I2C开发篇)

目录 前言 I2C 流程 Trasmint only mode(I2C_CON[1:0]2’b00) Mix mode (I2C_CON[1:0]2’b01 or I2C_CON[1:0]2’b11) Receive only mode (I2C_CON[1:0]2’b10) I2C 驱动参数配置 I2C 使用 1 Kernel space 2User space GPIO 模拟 I2C I2C 常见问题 前言 ROCKCHIP 系…

四、戴尔R630本地服务器Linux Centos7.9系统安装docker-ce-20.10.10-3.el7版本

如需查阅上一步骤,请点击下面链接:3、Linux Centos7.9系统的iDRAC远程管理、网络设置、SecureCRT远程登录终端、企业级静态ip地址配置-CSDN博客文章浏览阅读898次,点赞17次,收藏15次。iDRAC连接登录服务器远程管理。https://blog.csdn.net/weixin_67440240/article/details…

【Anaconda】Linux下Anaconda安装和虚拟环境配置

Linux下Anaconda安装和虚拟环境配置 一、安装anaconda二、conda虚拟环境管理三、jupyter相关启动部署四、遇到问题 下面介绍整体流程&#xff0c;遇到问题优先看“遇到问题章节”&#xff01; 一、安装anaconda 1.下载anaconda安装包 &#xff08;1&#xff09;可以选择在官网…

linux i2c-tools使用总结

1,安装iic-tools sudo apt install i2c-tools -y 2,查看有几条iic总线 [root@sino-platform:/root]# ls /dev/i2c- i2c-0 i2c-1 i2c-2 i2c-3 3,查看i2c命令 [root@sino-platform:/root]# i2c i2cdetect i2cdump i2cget i2cset 4,iic-help命令 [root@sino-platform…

postcss安装和使用(详细)

1,安装postcss&#xff1a; 在此之前需要安装有node.js 第一步 命令&#xff1a;cnpm install postcss-cli -g 第二步 命令&#xff1a;cnpm install postcss –g 推荐内容 2,下载autoprefixer插件&#xff0c;并创建postcss.config.js文件并写入配置代码 autoprefixer插件…