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;			//以十六进制形式输出整数a
	cout <<"Oct:" <<oct <<a <<endl;			//以八进制形式输出整数a
	
	cout <<endl;
	// 通过setbase输出
	cout <<"Use setbase to set the base:" <<endl;
	cout <<"Dec:" <<setbase(10) <<a <<endl;			//以十进制形式输出整数
	cout <<"Hex:" <<setbase(16) <<a <<endl;			//以十六进制形式输出整数a
	cout <<"Oct:" <<setbase(18) <<a <<endl;			//以八进制形式输出整数a
	
	cout <<endl;
	// 设置精度,宽度以及填充字符
	double PI = 3.1415926;
	cout <<"set precision 2: " <<setprecision(2) <<PI <<endl;		//改为2位小数
	cout <<setw(10) <<setprecision(2) <<PI <<endl;					//设置宽度为10
	cout <<setfill('*') <<setw(10) <<setprecision(2) <<PI <<endl;	//设置填充字符
	
	cout <<endl;
	// setiosfloags
	cout <<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);				//设置以十六进制形式输出整数a
	cout <<"Hex:" <<a <<endl;			
	cout.unsetf(ios::hex);
	cout.setf(ios::oct);				//设置以八进制形式输出整数a
	cout <<"Oct:" <<a <<endl;			
	cout.unsetf(ios::oct);
	
	cout <<endl;
	
	// 设置精度,宽度以及填充字符
	double PI = 3.1415926;
	cout <<"set precision 2, PI = " <<PI <<endl;			//显示PI值
	cout.width(30);											//设置宽度为30
	cout <<"set width, PI =" <<PI <<endl;	
	cout.width(30);											//设置宽度为30
	cout.fill('*');											// 置填充字符*
	cout <<"set fill, PI =" <<PI <<endl;
	
	cout <<endl;
	cout <<"set internal:" <<endl;
	cout.width(30);											//设置宽度为30
	cout.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);				//设置以十六进制形式输出整数a
	cout <<"Hex:" <<a <<endl;			
	cout.unsetf(ios::hex);
	cout.setf(ios::oct);				//设置以八进制形式输出整数a
	cout <<"Oct:" <<a <<endl;			
	cout.unsetf(ios::oct);
	
	cout <<endl;
	
	// 设置精度,宽度以及填充字符
	double PI = 3.1415926;
	cout <<"set precision 2, PI = " <<PI <<endl;			//显示PI值
	cout.width(30);											//设置宽度为30
	cout <<"set width, PI =" <<PI <<endl;	
	cout.width(30);											//设置宽度为30
	cout.fill('*');											// 置填充字符*
	cout <<"set fill, PI =" <<PI <<endl;
	
	cout <<endl;
	cout <<"set internal:" <<endl;
	cout.width(30);											//设置宽度为30
	cout.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相同。

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

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

相关文章

去除uni微信小程序button的边框

想要去除button的边框&#xff0c;如下未去除边框时&#xff0c;非常影响观感。 解决方法 使用伪元素::after&#xff0c;简单但是易忘&#xff0c;正常情况下,我直接是给button上加上一个类名直接设置border&#xff1a;none&#xff0c;但是这样是无效的&#xff0c;应该如下…

【软考】下篇 第13章 层次式架构设计理论与实践

目录 一、概述1.2 通用分层1.2 分层架构注意点 二、表现层(展示层)2.1 表现层设计模式&#xff08;MVC、MVP、MVVM&#xff09;2.2 使用XML设计表现层2.3 UIP2.4 表现层动态生成设计思想 三、中间层(业务层、业务逻辑层)3.1 组件设计3.2 工作流设计3.3 实体设计3.4 业务逻辑层框…

CC1310 Debug interface is locked

XDS110连接CC1310板子&#xff0c;打开Smart RF 弹出窗口如下&#xff1a; 解决办法&#xff1a; 1 打开SmartRF Flash Programmer 2 选择连接的设备CC1310, 弹出如下窗口&#xff0c;点击OK。 3 点击Tools图标&#xff0c;选择CC26XX/CC13XX Forced Mass Erase。 4 在弹出的…

分布式锁的三种实现方案

目录 为什么需要分布式锁实现一个分布式锁需要考虑的点如何实现一个分布式锁基于数据库的实现基于 zookeeper 实现基于 redis 实现 实际项目中好用的轮子 为什么需要分布式锁 传统的 jdk 锁&#xff0c;比如 synchronized, reentrantlock 只能在单机环境中使用分布式场景下&am…

5.26 基于UDP的网络聊天室

需求&#xff1a; 如果有人发送消息&#xff0c;其他用户可以收到这个人的群聊信息 如果有人下线&#xff0c;其他用户可以收到这个人的下线信息 服务器可以发送系统信息实现模型 模型&#xff1a; 代码&#xff1a; //chatser.c -- 服务器端实现 #include <stdio.h>…

FastAPI - 组织模块2

FastAPI没有强制指定某种格式来组织项目结构&#xff0c;开发者可以根据自己喜好和项目需要来定制自己的项目结构。 https://fastapi.tiangolo.com/zh/tutorial/bigger-applications/ 在项目根目录创建python包routers&#xff0c;然后创建member.py文件 member.py文件内容 …

互联网应用主流框架整合之AOP

SpringAOP基本概念和约定流程 在实际的开发中有些内容并不是面向对象能够解决的&#xff0c;比如数据库事务&#xff0c;对于企业级应用非常重要&#xff0c;比如在电商系统中订单模块和交易模块&#xff0c;一边是交易记录一边是账户数据&#xff0c;就需要对这两者有统一的事…

权限维持--linux

隐藏文件/夹&-开头文件 如何创建: 在文件名之前加.即可 touch .1.s 如何清除、查找&#xff1a; ls -al rm -fr -文件 已-开头的文件直接读取是不行的需要带目录 隐藏时间戳 ①用其他文件的时间 touch -r zww.php testq.txt 如何清除、查看&#xff1a; stat test…

大模型基础知识

文章目录 1. 位置编码1.1 绝对位置编码1.2 相对位置编码1.3 旋转位置编码2. 注意力机制2.1 MHA(muti head attention)2.2 MQA(muti query attention)2.3 GQA(grouped query attention)3. 大模型分类4. 微调方法4.1 Prompt Tuning4.2 Prefix Tuning4.3 Lora4.4 QLora5. La…

探索机器人智能设备:开启智慧生活新篇章

机器人智能设备作为科技创新的代表&#xff0c;正以其独特的魅力吸引着越来越多的关注。它们不仅具备高度的智能化和自主化能力&#xff0c;还能在各种场景下发挥出强大的功能。 机器人智能设备的张总说&#xff1a;在智能家居领域&#xff0c;机器人智能设备可以帮助我们实现家…

改进rust代码的35种具体方法-类型(十九)-避免使用反射

上一篇文章 从其他语言来到Rust的程序员通常习惯于将反思作为工具箱中的工具。他们可能会浪费很多时间试图在Rust中实现基于反射的设计&#xff0c;却发现他们所尝试的事情只能做得不好&#xff0c;如果有的话。这个项目希望通过描述Rust在反思方面做什么和不做什么&#xff0c…

2024年【西式面点师(中级)】新版试题及西式面点师(中级)考试试卷

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【西式面点师&#xff08;中级&#xff09;】新版试题及西式面点师&#xff08;中级&#xff09;考试试卷&#xff0c;包含西式面点师&#xff08;中级&#xff09;新版试题答案和解析及西式面点师&#xff08;…

手动安装maven依赖到本地仓库

使用mvn install命令安装jar包到指定的仓库。 命令如下&#xff1a; mvn install:install-file -Dmaven.repo.localC:\Users\liyong.m2\repository -DgroupIdcom.aspose -DartifactIdwords -Dversion18.4 -Dpackagingjar -DfileC:\Users\liyong\Desktop\jar\words-18.4.jar 解释…

JAVA智慧工厂制造生产管理MES系统,全套源码,多端展示(MES与ERP系统的区别和联系)

MES与ERP系统的区别和联系 MES制造执行系统&#xff0c;是一套面向制造公司车间执行层的生产信息化管理系统。MES 可觉得公司提供涉及制造数据管理、计划排产管理、生产调度管理、库存管理、质量管理、人力资源管理、工作中心、设备管理、工具工装管理、采购管理、成本管理、项…

谷歌忙于手动删除自己搜索引擎中奇怪的人工智能答案

该公司确认正在“迅速采取行动”消除人工智能工具的一些奇怪反应。 社交媒体上充斥着谷歌新的人工智能概述产品的例子&#xff0c;这些产品说了一些奇怪的话&#xff0c;从告诉用户在披萨上涂胶水到建议他们吃石头。混乱的推出意味着&#xff0c;随着各种表情包的发布&#xf…

DNS 解析过程

文章目录 简介特点查询方式⚡️1. 浏览器缓存2. 系统缓存&#xff08;hosts文件&#xff09;3. 路由器缓存4. 本地域名服务器5. 根域名服务器6. 顶级域名服务器7. 权限域名服务器8. 本地域名服务器缓存并返回9. 操作系统缓存并返回10. 浏览器缓存并访问流程图 总结 简介 DNS&a…

双向带头链表实现

目录 一. 逻辑结构图解 1. 节点中存储的值 2.逻辑实现 二. 各种功能实现 1. 创建节点函数 2. 初始化哨兵位 3. 尾插 4. 头插 5. 尾删 6. 头删 7. 打印链表值 8. 查找数据&#xff0c;返回节点地址 9. 指定地址后插入节点 10. 删除指定地址节点 11. 销毁链表 三.…

vue实现附件下载 获取到接口的图片,设置宽度100%样式

一、vue实现附件下载&#xff0c;使用a链接 <a class"btn flex_center" target"_blank" :href"localImgSrc(goodsDetail.attachment)" :download"localImgSrc(goodsDetail.attachment)" >立即下载 </a>二、 获取到接口…

七大获取免费https的方式

想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后&#xff0c;浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书&#xff0c;又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…

vue3(一):Vue3简介、创建vue3工程、Vue3中的响应式

目录 一.Vue3简介 1.性能提升 2.源码升级 3.拥抱ts 4.新特性 &#xff08;1&#xff09;Composition API&#xff08;组合API&#xff09;&#xff1a; &#xff08;2&#xff09;新的内置组件&#xff1a; &#xff08;3&#xff09;其他改变&#xff1a; 二.创建vue…