【C++ 输入输出】cin、cout、cerr 与格式化输出

1. 为什么需要输入输出?

程序需要与用户"交流":输出 让程序告诉用户结果,输入 让用户告诉程序数据。C++ 通过 <iostream> 库提供了三个最常用的流对象:

对象 含义 默认连接
cin 标准输入 键盘
cout 标准输出 屏幕
cerr 标准错误 屏幕(无缓冲,立即显示)

2. 基本使用:cin、cout、cerr

示例1:读取两个整数并输出它们的和

cpp 复制代码
#include <iostream>
using namespace std;

int main() {
    int a, b;
    cout << "请输入两个整数:";
    cin >> a >> b;
    int sum = a + b;
    cout << "它们的和是:" << sum << endl;
    return 0;
}

运行示例 (假设输入 10 20):

复制代码
请输入两个整数:10 20
它们的和是:30

示例2:使用 cerr 输出错误信息

cpp 复制代码
#include <iostream>
using namespace std;

int main() {
    int age;
    cout << "请输入年龄(0-120):";
    cin >> age;
    if (age < 0 || age > 120) {
        cerr << "错误:年龄超出合理范围!" << endl;
        return 1;   // 非0返回表示异常
    }
    cout << "您的年龄是:" << age << endl;
    return 0;
}

注意cerr 不受输出重定向影响,通常用于错误信息,且不经过缓冲区(立即显示)。

3. 格式化输出(iomanip 库)

C++ 提供了 <iomanip> 头文件中的操作符,用于精细控制输出格式。

3.1 控制整数进制

cpp 复制代码
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    int num = 255;
    cout << "十进制:" << dec << num << endl;   // 255
    cout << "十六进制:" << hex << num << endl; // ff
    cout << "八进制:" << oct << num << endl;   // 377
    // 恢复十进制
    cout << dec << "恢复十进制:" << num << endl;
    return 0;
}

3.2 控制浮点数精度与格式

cpp 复制代码
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    double pi = 3.1415926535;
    // 设置固定小数位数(小数点后2位)
    cout << fixed << setprecision(2) << pi << endl; // 3.14
    // 科学计数法
    cout << scientific << setprecision(4) << pi << endl; // 3.1416e+00
    // 恢复默认浮点输出(自动选择)
    cout << defaultfloat << pi << endl;
    return 0;
}

3.3 设置宽度与填充字符

cpp 复制代码
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    cout << setw(10) << "ID" << setw(10) << "Name" << endl;
    cout << setw(10) << 1001 << setw(10) << "Alice" << endl;
    cout << setw(10) << 1002 << setw(10) << "Bob" << endl;
    // 填充字符改为 '*'
    cout << setfill('*') << setw(10) << 1003 << setw(10) << "Tom" << endl;
    return 0;
}

输出:

复制代码
        ID      Name
      1001     Alice
      1002       Bob
******1003*******Tom

4. 内存模型讲解(浅显易懂)

当我们执行 cin >> acout << "hello" 时,背后发生了什么?来看内存中的"输入输出缓冲区"模型。

复制代码
用户键盘输入 "10 20\n"
       ↓
┌─────────────────────────────────────────┐
│              输入缓冲区 (内存)          │
│  [ '1' , '0' , ' ' , '2' , '0' , '\n' ] │
└─────────────────────────────────────────┘
       ↓  cin 从缓冲区解析整数
       ↓
┌──────────────┐   ┌──────────────┐
│  变量 a (栈) │   │  变量 b (栈) │
│    10        │   │    20        │
└──────────────┘   └──────────────┘
  • 输入缓冲区 :当你在键盘上敲击并按下回车,操作系统把字符序列存入内存中的"输入缓冲区"。cin 从该缓冲区读取并转换成对应类型(比如 int)。
  • 输出缓冲区cout << "结果:" << sum << endl; 先将数据写入"输出缓冲区"(内存中的一块区域),当遇到 endl 或缓冲区满时,系统才真正把内容显示到屏幕(或写入文件)。这样做是为了提高效率(减少慢速 I/O 操作)。

cerr 的特殊性cerr 不经过缓冲区,直接输出到屏幕。这意味着即使程序崩溃,错误信息也能立即显示,不会因为缓冲区没刷新而丢失。

5. 常见错误与避坑

错误写法 问题
cin >> a, b; 逗号不能用于连续输入,应使用 >> 连接:cin >> a >> b;
输入 10 20 但变量类型是 char 类型不匹配,cin 会失败,后续读取无效
cout << setprecision(2) << 3.1415; 没有 fixed 设置的是总有效位数,而不是小数位数
忘记 #include <iomanip> 使用 setwsetprecision 等会编译错误
cerrcout 混用导致顺序奇怪 因为 cout 有缓冲,cerr 无缓冲,可能先显示 cerr 内容再显示 cout

6. 练习题

题目:编写一个程序,要求:

  1. 提示用户输入一个浮点数(例如 123.456789)。
  2. 读取该浮点数,并分别用以下格式输出:
    • 默认格式(保留6位有效数字)
    • 固定小数点后3位
    • 科学计数法(小数点后4位)
  3. 再提示用户输入一个整数(例如 255),分别以十进制、十六进制、八进制输出,每个数占宽8格,用 0 填充前导空白。

示例输入

复制代码
123.456789
255

期望输出

复制代码
默认格式:123.457
固定3位小数:123.457
科学计数法:1.2346e+02
十进制:00000255
十六进制:000000ff
八进制:00000377

提示

  • 使用 fixedscientificsetprecisionsetwsetfillhexoctdec
  • 切换进制后如需恢复十进制,记得使用 dec

上期练习答案

cpp 复制代码
#include <iostream>
using namespace std;

int main() {
    cout << "My name is Alice" << endl;
    cout << "I am learning C++!" << endl;
    return 0;
}

总结 :今天我们学习了 C++ 的标准输入输出 cincoutcerr,掌握了使用 <iomanip> 进行格式化输出的常用方法,并理解了缓冲区在内存中的作用。下一篇文章我们将深入注释与编码风格,继续夯实基础。

快去动手写代码,用格式化输出做出漂亮的报告吧!

相关推荐
汀、人工智能2 小时前
[特殊字符] 第46课:验证二叉搜索树
数据结构·算法·数据库架构·图论·bfs·验证二叉搜索树
3GPP仿真实验室2 小时前
【MATLAB源码】水声:时变信道估计仿真平台
开发语言·matlab
froginwe112 小时前
Eclipse 关闭项目详解
开发语言
靠沿2 小时前
【递归、搜索与回溯算法】专题三——穷举vs暴搜vs深搜vs回溯vs剪枝
算法·机器学习·剪枝
香蕉鼠片2 小时前
排序算法C++
c++·算法·排序算法
wjs20242 小时前
《jQuery Validate》深度解析与应用指南
开发语言
森G2 小时前
51、Move方式创建线程---------多线程
c++·qt
xiaoye-duck2 小时前
《算法题讲解指南:优选算法-栈》--65.删除字符中的所有相邻重复项,66.比较含退格的字符串,67.基本计算器II,68.字符串解码,69.验证栈序列
c++·算法·
Q741_1472 小时前
每日一题 力扣 3653. 区间乘法查询后的异或 I 模拟 数学 位运算 C++ 题解
c++·数学·算法·leetcode·力扣·模拟