C++面向对象程序设计 - 标准输出流

        在C++中,标准输出流通常指的是与标准输出设备(通常是终端或控制台)相关联的流对象。这个流对象在C++标准库中被定义为std::cout、std::err、std::clog,它们是std::ostream类的一个实例。

一、cout,cerr和clog流

        ostream类定义了3个输出流对象,即cout,cerr,clog。

1.1cout流对象

        (1) cout是console output的缩写,意为控制台(终端显示器)的输出。它不是C++预定义的关键字,而是ostream流类的对象,在iostream中定义。顾名思义,流是流动的数据,cout流是流向输出(显示设备)的数据,cout流中的数据是用流插入运算符“<<“顺序加入的。

        示例如下:

cout <<"Hello World!" <<"I am learning C++.";

        cout流是容纳数据的载体,而并不是运算符。cout将它们输送到输出设备上显示,在显示设备上输出”Hello Wordl! I am learning C++.“。

        (2) 在使用"cout <<"输出基本类型的数据时,不必考虑数据是什么类型,系统会自动判断数据的类型,并根据类型选择调用与之匹配的运算符重载函数。示例如下:

cout <<10.0f <<100.58 <<'=' <<"operator"; 

        (3) cout流在内存中对应开辟了一个缓冲区,用来存储流中的数据,当向cout流插入一个endl时,不论缓冲区是否已满,都立即输出流中所有数据,然后插入一个换行符,并刷新流(清空缓冲区)。示例如下:

cout <<"Hello World" <<endl;
cout <<"I am learning C++" <<endl;

        注意的是如果插入换行符”\n“,则只是换行而已,并不是刷新cout流,与endl刷新流是清空缓冲区不是一回事。

        (4) 在iostream中只对”<<“和">>"运算符用于标准类型数据的输入输出进行了重载,但未对用户声明的类型数据的输入输出进行重载。所以用户可以声明新的类型,并用”<<“和">>"运算符对其进行输入输出另作重载。

1.2 cerr流对象

        cerr流对象是标准出错流,cerr流已被指定为与显示器关联,cerr作用是向标准出错设备(standard error device)输出有关的出错信息。cerr是console error的缩写,意为在控制台(显示器)显示出错的信息。

        注意的是cerr和cout的作用和用法虽然差不多,但是有一点不同的是,cout流通常是传送到显示设备输出,也可以被重定向输出到磁盘文件,而cerr流中的信息只能显示输出。

        通过解一元二次方程ax^{2}+bx+c=0,其一般解为x_{1,2}=\frac{-b\pm \sqrt{b^{2}-4ac}}{2a},但若a=0,或b^{2}-4ac<0时,用公式出错。编写程序,从键盘输入a、b、c的值,求x_{1}x_{2}。如果a=0或b^{2}-4ac<0,输出错误信息。代码示例如下:

#include <iostream>
#include <cmath>
using namespace std;int main(){float a, b, c, disc;cout <<"Please enter the values of a, b, c:";cin >>a >>b >>c;// 如果a等于0输出错误信息if(a == 0){cerr <<"a is equal to zero, error!" <<endl;} else{// 如果b * b - 4 * a * c)结果小于0 ,输出错误信息if( (disc = b * b - 4 * a * c) < 0 ){cerr <<"Erro: dist=b*b-4*a*c<0" <<endl;} // 满足条件,则正常输出结果else{cout <<"x1 = " <<(-b + sqrt(disc) / (2*a)) <<endl;cout <<"x2 = " <<(-b - sqrt(disc) / (2*a)) <<endl;}}return 0;
}

1)如输入a=0,运行后结果如下图:

2)如输入b^{2}-4ac<0,运行后结果如下图:

3)如满足条件,运行后结果如下图:

1.3 clog流对象

        clog流对象也是标准出错流,它是console log的缩写,作用与cerr相同,都是在终端显示器上显示出错信息。它们之间只是有微小区别。cerr是不经过缓冲区,直接向显示器上输出有关信息,而clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出。

        示例如下:

#include <iostream>
using namespace std;int main(){clog <<"This is a message to the C library's error stream." <<endl;clog.flush();		//确保消息被立即刷新到设备return 0;
}

        运行结果如上图:

        实际编程中,cerr通常用于输出需要立即显示的错误消息或调试信息,而clog用于记录那些稍后再处理的更详细的日志信息。这只是常见的约定,并不是强制的。

二、格式输出

        在输出数据时,为简便起见,往往不指定输出的格式,由系统根据数据的类型采取默认的格式,但有时希望数据按指定的格式输出,如要求以十六进制或八进制形式输出一个整数,对输出的小数只保留两位小数等。

2.1 使用控制符控制输出格式

        以下为输出数据的控制符,如下表:

控制符作用
dec

设置整数的基数为10

hex设置整数的基数为16
oct设置整数的基数为8
setbae(n)设置整数的基数为n(n只能是8,10,16三者之一)
setfill(c)设置填充字符c,c可以是字符常量或字符变量
setprecision(n)设置实数的精度为n位,在以一般十进制小数形式输出时n代表有效数字。在以fixed(固定小数位数)形式和scientific(指数)形式输出时n为小数位数。
setw(n)设置字段宽度为n位
setiosflags(ios::fixed)设置浮点数以固定的小数位数显示
setiosflags(ios::scientific)设置浮点数以科技记数法(即指数形式)显示
setiosflags(ios::left)输出数据左对齐
setiosflags(ios::right)输出数据右对齐
setiosflags(ios::skipws)忽略前导的空格
setiosflags(ios::uppercase)在以科学记数法输出E和以十六进制输出字母X时以大写表示
setiosflags(ios::showpos)输出正数时给出”+“号
resetioflags()终止已设置的输出格式状态,在括号中应指定内容

        注意的是,这些控制符是在头文件iomanip中定义的,因而程序中应当包含头文件ipmanip。以下通过案例了解以上的方法,代码如下:

#include <iostream>
#include <iomanip>
using namespace std;int main(){int a = 20;			//定义整数a值为20// 输出信息cout <<"Dec:" <<dec <<a <<endl;			//以十进制形式输出整数cout <<"Hex:" <<hex <<a <<endl;			//以十六进制形式输出整数acout <<"Oct:" <<oct <<a <<endl;			//以八进制形式输出整数acout <<endl;// 通过setbase输出cout <<"Use setbase to set the base:" <<endl;cout <<"Dec:" <<setbase(10) <<a <<endl;			//以十进制形式输出整数cout <<"Hex:" <<setbase(16) <<a <<endl;			//以十六进制形式输出整数acout <<"Oct:" <<setbase(18) <<a <<endl;			//以八进制形式输出整数acout <<endl;// 设置精度,宽度以及填充字符double PI = 3.1415926;cout <<"set precision 2: " <<setprecision(2) <<PI <<endl;		//改为2位小数cout <<setw(10) <<setprecision(2) <<PI <<endl;					//设置宽度为10cout <<setfill('*') <<setw(10) <<setprecision(2) <<PI <<endl;	//设置填充字符cout <<endl;// setiosfloagscout <<setiosflags(ios::scientific) <<setprecision(8);				// 按指数形式输出8位小数cout <<"PI = " <<PI <<endl;											// 指数形式输出PI值cout <<"precision 4 PI = " <<setprecision(4) <<PI <<endl;			// 指数形式 输出PI为4位小数cout <<"Left aligned, PI = " <<left <<setw(20) <<PI <<endl;			// 左侧齐cout <<"Right aligned, PI = " <<right <<setw(20) <<PI <<endl;		// 右对齐 // 使用大写字母cout <<"Uppercase: " <<uppercase <<hex <<255 <<endl;				//以16进制显示并使用大写字母cout <<"Show positive sign:" <<showpos <<PI <<endl;// 注意此时cout <<"Fixed, PI = " <<setiosflags(ios::fixed) <<PI <<endl;		// 改为小数形式输出return 0;
}

        运行结果如下图:

        最后代码试图将科学记数法设置为小数位,但是(cout <<"Fixed, PI = " <<setiosflags(ios::fixed) <<PI <<endl;)输出结果为+0XC.90FDA6896C25P-2,它可能是由于被setiosflags错误的解析导致的,通过resetiosflags重置清理掉前面的科学记数法格式即可。在上述代码后面追加以下代码即可:

// 重置指数形式
cout <<"reset ios flags:" <<endl;
cout <<resetiosflags(ios::scientific | ios::showpos);
cout <<"PI = " <<PI <<endl;

        resetiosflags中ios::scientific是清除科学记数法,ios::showpos是清除数值前面”+“号,输出结果如下图:

2.2 用流对象的成员函数控制输出格式

        除了可以用控制符来控制输出格式,还可以通过调用流对象cout中用于控制输出格式的成员函数来控制输出格式。用于控制输出格式的常用的成员函数如下表:

流成员函数与之作用相同的控制符作用
precision(n)setprecision(n)设置实数的精度为n位
width(n)setw(n)设置字段宽度为n位
fill(c)setfill(c)设置填充字符c
setf()setiosflags()设置输出格式状态,括号中应给出格式状态,内容与控制符setiosflags括号中的内容相同。
unsetf()resetiosflag()终止已设置的输出格式状态,在括号中应该指定内容

        格式标志在类ios中被定义为枚举值,因此在引用这些格式标志时要在前面加上类名ios和域运算符"::"。格式标志如下表:

格式标志作用
ios::left输出数据在本域范围内向左对齐
ios::right输出数据在本域范围内向右对齐
ios::internal数值的符号位在域宽度内左对齐,数值右对齐,中间由填充字符填充
ios::dec设置整数的基数为10
ios::oct设置整数的基数为8
ios::hex设置整数的基数为16
ios::showbase强制输出整数的基数(八进制数以0打头,十六进制数以0x打头)
ios::showpoint强制输出浮点数的小点和尾数0
ios::uppercase在以科学记数法格式E和以十六进制输出字母时以大写表示
ios::showpos对正数显示”+“号
ios::scientific浮点数以科学记数法格式输出
ios::fixed浮点数以定点格式(小数形式)输出
ios::unitbuf每次输出之后刷新所有的流
ios::stdio每次输出之后清除stdout, stderr

        下面使用流控制成员输出之前案例数据,代码如下:

#include <iostream>
#include <iomanip>
using namespace std;int main(){int a = 20;			//定义整数a值为20// 输出信息cout.setf(ios::dec);				//设置以十进制形式输出整数cout <<"Dec:" <<a <<endl;cout.unsetf(ios::dec);			cout.setf(ios::hex);				//设置以十六进制形式输出整数acout <<"Hex:" <<a <<endl;			cout.unsetf(ios::hex);cout.setf(ios::oct);				//设置以八进制形式输出整数acout <<"Oct:" <<a <<endl;			cout.unsetf(ios::oct);cout <<endl;// 设置精度,宽度以及填充字符double PI = 3.1415926;cout <<"set precision 2, PI = " <<PI <<endl;			//显示PI值cout.width(30);											//设置宽度为30cout <<"set width, PI =" <<PI <<endl;	cout.width(30);											//设置宽度为30cout.fill('*');											// 置填充字符*cout <<"set fill, PI =" <<PI <<endl;cout <<endl;cout <<"set internal:" <<endl;cout.width(30);											//设置宽度为30cout.fill(' ');											// 置填充字符*cout.setf(ios::internal | ios::showpos);cout <<PI <<endl;cout.unsetf(ios::internal | ios::showpos);cout <<endl;// 标记为科学记数法cout.setf(ios::scientific);								// 设置为科学记数法cout <<"set scientific, PI = " <<PI <<endl;cout.precision(4);										//保留4位小数cout <<"precision 4, PI = " <<PI <<endl;cout <<endl;// 指定用定点形式输出cout.setf(ios::fixed);cout <<"Fixed, PI = " <<PI <<endl;cout.unsetf(ios::fixed);return 0;
}

        运行后结果如下图:

        这里同样,在最后输出时PI未得到想要结果,这是因为在设置科学记数法格式cout.setf(ios::scientific)未及时清除设置的格式标志导致的,所以添加cout.unsetf(ios::scientific)及时清除以避免影响后续输出。

        完整代码如下:

#include <iostream>
#include <iomanip>
using namespace std;int main(){int a = 20;			//定义整数a值为20// 输出信息cout.setf(ios::dec);				//设置以十进制形式输出整数cout <<"Dec:" <<a <<endl;cout.unsetf(ios::dec);			cout.setf(ios::hex);				//设置以十六进制形式输出整数acout <<"Hex:" <<a <<endl;			cout.unsetf(ios::hex);cout.setf(ios::oct);				//设置以八进制形式输出整数acout <<"Oct:" <<a <<endl;			cout.unsetf(ios::oct);cout <<endl;// 设置精度,宽度以及填充字符double PI = 3.1415926;cout <<"set precision 2, PI = " <<PI <<endl;			//显示PI值cout.width(30);											//设置宽度为30cout <<"set width, PI =" <<PI <<endl;	cout.width(30);											//设置宽度为30cout.fill('*');											// 置填充字符*cout <<"set fill, PI =" <<PI <<endl;cout <<endl;cout <<"set internal:" <<endl;cout.width(30);											//设置宽度为30cout.fill(' ');											// 置填充字符*cout.setf(ios::internal | ios::showpos);cout <<PI <<endl;cout.unsetf(ios::internal | ios::showpos);cout <<endl;// 标记为科学记数法cout.setf(ios::scientific);								// 设置为科学记数法cout <<"set scientific, PI = " <<PI <<endl;cout.precision(4);										//保留4位小数cout <<"precision 4, PI = " <<PI <<endl;cout.unsetf(ios::scientific);cout <<endl;// 指定用定点形式输出cout.setf(ios::fixed);cout <<"Fixed, PI = " <<PI <<endl;cout.unsetf(ios::fixed);return 0;
}

        输出结果如下图:

三、用流成员函数put输出字符

        在程序中一般用cout和插入运算符”<<“实现输出,cout流在内存中有相应的缓冲区。有时有些特殊输出要求,ostream类还提供了专用于输出单个字符的成员函数put。

3.1 ASCII码输出

        如下示例代码:

#include <iostream>
using namespace std;int main(){// ASCII字符码输出int arr[] = {71, 79, 79, 68};		// 字母GOOD分别对应ASCII码71,79,68// 循环输出单个字符for(int i = 0; i<4; i++) cout.put(arr[i]);cout.put('\n');return 0;
}

        运行结果如下图:

3.2 字符串反转

        也可使用cout.put()对字符串进行反转输出,示例代码如下:

#include <iostream>
#include <string>
using namespace std;int main(){string message = "Hello World!";		//定义字符串信息const char *str = message.c_str();		//将字符串转换为char字符数组// 循环输出字符信息,倒序输出for(int i = message.length() - 1; i >= 0; i--) cout.put(*(str + i));// 换行cout.put('\n');return 0;
}

        运行后结果如下图:

        字符指针变量str指向第1个字符'H', a+1则是第2个字符'e'的地址,*(a+1)的值就是’e'。指针的相关知识前面已讲解过,想了解朋友可以翻看下,地址:C++面向对象程序设计 - 对象指针和this指针_面向对象版本的指针-CSDN博客

3.3 putchar函数

        除了可以用cout.put函数输出一个字符外,还可以用putchar函数输出一个字符。putchar函数是C语言中使用的,在stdio.h头文件中定义的。所以3.2中示例可以修改为putchar函数,代码如下:

#include <iostream>
#include <string>
using namespace std;int main(){string message = "Hello World!";		//定义字符串信息const char *str = message.c_str();		//将字符串转换为char字符数组// 循环输出字符信息,倒序输出for(int i = message.length() - 1; i >= 0; i--) putchar(*(str + i));// 换行cout.put('\n');return 0;
}

        运行后输出结果与3.2相同。

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

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

相关文章

echarts(6大基础图表)的使用

目录 一、vue2挂载 二、柱状图 2.1、基础柱状图介绍 2.2、标记&#xff1a;最大值\最小值(markPoint)、平均值(markLine) 2.3、显示&#xff1a;数值显示(label)、柱子宽度(barWidth)、横向柱状图 三、折线图 3.1、标记&#xff1a;最大值\最小值(markPoint)、平均值(ma…

R可视化:组间点图比较

散点组间比较 散点组间比较 介绍 ggplot2绘制散点组间比较加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE)library(tidyverse) library(ggplot2) library(ggprism) library(ggbeeswarm) library(rstatix)rm(list = ls()) options(stringsAsFactors = F) o…

android11禁止进入屏保和自动休眠

应某些客户要求&#xff0c;关闭了开机进入屏保&#xff0c;一段时间会休眠的问题。以下diff可供参考&#xff1a; diff --git a/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/overlay/frameworks/base/packages/SettingsProvider/res/value…

Python3 笔记:repr() 函数

repr() 函数将对象转化为供解释器读取的形式。 语法&#xff1a; repr(object) 返回一个对象的 string 格式。 tuple1 (1,2,3) print(type(repr((tuple1)))) # 运行结果&#xff1a;<class str> repr(str)与在字符串前加上“r”或“R”的原理有点相似&#xff0c;但…

node模块的本质

对于一个模块而言&#xff0c;有两个关键的地方&#xff0c;一是有自己的作用域&#xff0c;二是有对外暴露的接口 不知道大家有没有想过这样一个问题&#xff0c;模块是怎么实现上面两个特性的呢&#xff1f;其实通过一个 立即执行函数 就可以了 实际上 Node 在编译的时候&a…

常见5大开发进度盲点问题及解决方案

在软件开发项目中&#xff0c;识别并解决常见的进度管理盲点问题&#xff0c;对于确保项目按时、按预算、高质量完成至关重要。它直接关系到项目能否顺利进行&#xff0c;忽视任何一个问题&#xff0c;都可能导致项目延期、成本超支、质量下降&#xff0c;甚至项目失败。 因此&…

IT技术培训班:实用还是虚幻?

在学习IT技术的过程中&#xff0c;我经常被各种五花八门的技术培训班所安利。这些培训班以各种方式向我宣传&#xff0c;声称可以快速提升技能、获得认证、找到高薪工作等&#xff0c;让我不禁怀疑&#xff1a;在培训班里学技术真的有用吗&#xff1f;我对此抱有怎样的态度呢&a…

香橙派华为昇腾CANN架构编译opencv4.9

香橙派华为升腾AI盒子 为啥要编译opencv4.9.0&#xff0c; 因为在4.9.0 中增加了华为昇腾CANN的外接开发库&#xff0c;下图为盒子外观&#xff0c;此次一接到这个盒子&#xff0c;立刻开始开箱操作&#xff0c;首先就是要编译opencv4.9&#xff0c;以前在香橙派3588 的盒子中…

大模型应用:LLM基本原理及应用场景

1.背景 23年以来&#xff0c;随着OpenAI公司的ChatGPT横空出世&#xff0c;大模型一词开始火爆全球。国内外以OpenAI、Google、百度、阿里、字节等大厂为代表&#xff0c;相继推出一系列大模型及其应用&#xff0c;涉及社交、问答、代码助手等多个方面。 目前主流的大模型及产…

Echarts - 多个页面内有N个 echarts 图表,封装组件 CommonEcharts 快捷实现

目录 子组件父组件使用注意 option 文件效果展示相关数据处理&#xff08;代码备份 - 可不看&#xff09;数据处理后页面展示 子组件 CommonEcharts.vue <template><div><div v-for"id in domId" :id"id" :key"id" class"…

代码随想录算法训练营Day53 | 1143.最长公共子序列、1035.不相交的线、53. 最大子序和 | Python | 个人记录向

本文目录 1143.最长公共子序列做题看文章 1035.不相交的线做题看文章 53. 最大子序和做题看文章 以往忽略的知识点小结个人体会 1143.最长公共子序列 代码随想录&#xff1a;1143.最长公共子序列 Leetcode&#xff1a;1143.最长公共子序列 做题 无思路。 看文章 dp[i][j]&…

基于事件的架构工作机制和相关产品

基于事件的架构 基于事件的架构可否这样理解&#xff0c;每个事件相当于传统API的一次函数调用请求&#xff0c;比如Add(123,456)。区别在于&#xff0c;基于事件的架构只是把这个请求发出&#xff0c;并不急于得到结果&#xff0c;而是等合适的子系统处理完这个请求&#xff…

go select

select 是与 switch 相似的控制结构&#xff0c;与 switch 不同的是&#xff0c;select 中虽然也有多个 case&#xff0c;但是这些 case 中的表达式必须都是 channel 的收发操作。 select 能够让 goroutine 同时等待多个 channel 可读或者可写&#xff0c;在多个 channel 状态改…

使用awk对nginx access.log进行统计分析

nginx可以配置访问日志&#xff0c;如果我们要对日志文件进行统计分析&#xff0c;在linux环境下可以借助awk命令完成。 日志格式配置如下所示&#xff1a; log_format access_json {"timestamp":"$time_iso8601","host":"$server_addr&qu…

Flutter 中的 AnimatedOpacity 小部件:全面指南

Flutter 中的 AnimatedOpacity 小部件&#xff1a;全面指南 在Flutter中&#xff0c;动画是一种为用户提供视觉反馈和增强用户体验的强大工具。AnimatedOpacity是Flutter动画库中的一个组件&#xff0c;它允许你通过改变一个组件的透明度来创建淡入和淡出效果。本文将详细介绍…

章十五、Maven —— Maven 简介、Maven 开发环境搭建、命令、打包案例

一、 Maven 简介 Maven 是 Apache 软件基金会的一个开源项目&#xff0c;是一个优秀的项目构建工具&#xff0c;它用来帮助开发者管理项目中的 jar&#xff0c;以及 jar 之间的依赖关系&#xff08;在A.jar文件中用到了B.jar&#xff09;、完成项目的编译&#xff08;.java -&g…

Compose Button移除水波纹效果

一、背景 在使用Compose实现Button按钮时&#xff0c;设计要求移除按钮的水波纹效果&#xff0c;只保留按压效果&#xff0c;经查Compose1.4.3版本中&#xff0c;并没有直接移除水波纹的能力 二、遇到问题 经过多次尝试&#xff0c;使用Compose的Button组件始终无法实现目标效…

html通过数据改变,图片跟着改变

改变前 改变后 通过数据来控制样式展示 <template><div>通过num控制图标是否更改{{num}}<div class"box"><!-- 如果num大于1则是另一种&#xff0c;样式&#xff0c;如果小时1&#xff0c;则是另一种样式 --><div class"item&qu…

android怎么告诉系统不要回收

在Android中&#xff0c;如果你想告诉系统不要回收你的应用程序&#xff0c;可以通过设置Activity的属性来实现。你可以设置android:configChanges属性&#xff0c;指定在哪些配置更改时不重新创建Activity。 例如&#xff0c;如果你想指示系统在屏幕方向更改时不要重新创建Ac…

又是一知识点

1.说一下什么是mvvm模式 Model代表数据模型&#xff0c;数据和业务逻辑都在Model层中定义&#xff1b;View代表UI视图&#xff0c;负责数据的展示&#xff1b;ViewModel负责监听Model中数据的改变并且控制视图的更新&#xff0c;处理用户交互操作&#xff1b; View 的变化会自…