C++笔记1:操纵符输入输出

2024-02-14 06:12
文章标签 c++ 笔记 输入输出 操纵

本文主要是介绍C++笔记1:操纵符输入输出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++操纵符用来控制输出控制,一是输出的形式,二是控制补白的数量和位置。本文记录一下,在一些笔试的ACM模式可能有用。其中1-4节的部分是关于格式化输入输出操作,5-6节的部分是关于未格式化输入输出操作。

1. 控制布尔值的格式

一般我们用cout打印bool值为1或0,如果我们要打印为true或false,那么我们可以对流使用boolalpha操作符:

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

输出的结果是:

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

操作符boolalpha会改变格式状态,会影响下一个和随后的输出,如果我们不想影响到后面的格式输出,我们需要使用另一个操纵符noboolalpha改变格式。

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

2. 控制整型的进制

我们常常需要将整型的进制转换为十六进制、八进制或十进制:

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

输出的结果是:

default: 20 1024
octal: 24 2000
hex: 14 400
decimal: 20 1024

如果我们要在输出中指出进制:

  • 前导0x表示十六进制
  • 前导0表示八进制
  • 无前导字符串表示十进制

我们可以使用showbase修改上面的程序:

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

输出的结果:

default: 20 1024
octal: 024 02000
hex: 0x14 0x400
decimal: 20 1024

如果要显示整型数为大写的十六进制,我们可以使用uppercase:

cout << uppercase << showbase << hex // 打印整型值显示进制<< "printed in hexadecimal: " << 20 << " " << 1024 << endl;
cout << nouppercase << noshowbase << dec << endl; // 恢复流状态

输出的结果:

printed in hexadecimal: 0X14 0X400

3. 控制浮点数格式

浮点数的格式主要有三种控制格式:

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

默认情况下:

  • 浮点值按六位数字精度打印
  • 如果浮点值没有小数部分,则不打印小数点,根据浮点数的值选择打印成定点十进制或科学记数法形式
  • 非常大或非常小的数打印为科学计数法,其他值打印为定点十进制形式。

3.1 指定打印精度

可以式运算precision成员或使用setprecision操纵符来改变精度

  • precision成员是重载的。一个版本接受一个int值,将精度设置为此值,并返回旧精度值。另一个版本不接受参数,返回当前的精度值。
  • setprecision操纵符接受一个参数,用来设置精度。
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{cout << "Precision: " << cout.precision()<< ", Value: " << sqrt(2.0) << endl;cout.precision(12);cout << "Precision: " << cout.precision()<< ", Value: " << sqrt(2.0) << endl;cout << setprecision(3);//要包含iomanip库cout << "Precision: " << cout.precision()<< ", Value: " << sqrt(2.0) << endl;
}

输出的结果:

Precision: 6, Value: 1.41421
Precision: 12, Value: 1.41421356237
Precision: 3, Value: 1.41

下表是定义在iostream里的其他操纵符。
在这里插入图片描述

3.2 指定浮点数的记数法

除非要控制浮点数的表示形式,否则由标准库选择记数法是最好的方式。

我们可以强制一个流使用科学记数法、定点十进制或十六进制记数法。

  • 操纵符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) << '\n\n';

输出的结果:

default format: 141.421
scientific: 1.414214e+02
fixed decimal: 141.421356
hexadecimal: 0x8.d6bde009b35cp+4
use defaults: 141.4212570

3.3 打印小数点

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

cout << 10.0 << endl;
cout << showpoint << 10.0<< noshowpoint << endl;

输出的结果:

10
10.0000

3.4 输出补白

当按列打印数据的时候,我们常常需要非常精细地控制数据格式,标准库提供了一些操纵符帮助我们完成所需的控制:

  • setw指定下一个数字或字符串值的最小空间,类似endl,不改变输出流的内部状态,它只决定下一个输出的大小。
  • left表示左对齐输出
  • right表示右对齐输出,右对齐是默认的格式
  • internal控制负数的符号的位置,它左对齐符号,右对齐值,用空格填满所有中间的空间
  • setfill允许一个字符代替默认的空格来补白输出
iomanip的操作符含义
setfill(ch)用ch填充空白
setprecision(ch)将浮点精度设置为n
setw(w)读或写值的宽度为w个字符
setbase(b)将整数输出为b进制
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) << i << "next col" << '\n'<< "d: " << setw(12) << d << "next col" << '\n'<< setfill(' ');//恢复正常的补白字符

输出的结果:

i: -16next col
d: 3.14159next col
i: -16 next col
d: 3.14159 next col
i: -16next col
d: 3.14159next col
i: - 16next col
d: 3.14159next col
i: -#########16next col
d: #####3.14159next col

4. 控制输出格式

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

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

如输入

a  b         c

输出则为:

abc

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

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

如输入

a b   c

输出则为:

a b   c

5. 单字节操作

我们可以使用get和put来读取和写入一个字符

char ch;
while (cin.get(ch))cout.put(ch);

在这里插入图片描述

一般情况下,在读取下一个值之前,标准库保证我们可以退回最多一个值,即标准库保证在中间不进行读取操作的情况下能连续调用putback或unget。

函数peek和无参的get以int类型从输入流返回一个字符,它首先把要返回的字符先转换为unsigned char,然后将结果提升到int。这样返回的int确保是正值。标准库使用负值表示文件尾,这可以保证与任何合法字符的值都不同,头文件cstdio定义了一个名为EOF的const,可以检测从get返回的值是不是文件尾,而不用记忆文件尾的实际数值

int ch;
while ((ch = cin.get()) != EOF)cout.put(ch);

6. 多字节操作

有时我们需要使用IO操作一次处理大块的数据,如果我们需要自己分配并管理用来保存和提取数据的字符数组,这些操作容易出错,且有时速度也是我们需要考虑的,下表给出了多字节操作:

在这里插入图片描述
get和getline函数接受相同的参数,他们的行为类似但不相同,在两个函数中,sink都是一个charuuzu ,用来保存数据,两个函数都一直读取数据,直至下面条件之一发生:

  • 已读取的size-1字符
  • 遇到了文件尾
  • 遇到了分隔符
    两个函数的差别是处理分隔符的方式:get将分隔符留作istream中的下一个字符,而getline则读取并丢弃分隔符。无论哪个函数都不会将分隔符保存在sink中。常见的错误是本想从流里删除分隔符,但却忘了做。

一个常见的错误是将get或peek的返回值赋予一个char而不是一个int,如果在一台char被实现为unsigned char的机器上,下面的循环永远不会停止:

char ch;
while ((ch = cin.get()) != EOF)cout.put(ch);

当get返回EOF时会转换为一个unsigned char,转换得到的值和EOF的int不相等,循环不会停止。而如果char被实现为signed char的机器上,我们不能确定循环的行为。

这篇关于C++笔记1:操纵符输入输出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/707703

相关文章

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)