cin 和 cout 是 C++ 标准输入 / 输出流(<iostream> 库)的核心对象,分别对应标准输入(键盘)和标准输出(控制台),基于流操作符(>> 用于 cin,<< 用于 cout)实现数据的输入输出,是 C++ 替代 C 语言 scanf/printf 的面向对象方案,核心优势是类型安全和可扩展性。
一、核心基础
1. 头文件与命名空间
使用 cin/cout 必须包含 <iostream> 头文件,且需访问 std 命名空间(两种方式):
// 方式1:全局引入(简化代码,推荐入门使用)
#include <iostream>
using namespace std;
// 方式2:显式指定(避免命名冲突,推荐大型项目)
#include <iostream>
std::cout << "Hello";
std::cin >> a;
2. 基本语法
| 操作 | 语法 | 说明 |
|---|---|---|
| 输出(cout) | cout << 数据1 << 数据2 << ...; | 链式输出,支持所有基础类型,自动匹配类型 |
| 输入(cin) | cin >> 变量1 >> 变量2 >> ...; | 链式输入,数据存入变量,自动匹配类型 |
二、cout 核心用法(输出)
1. 基础输出(无格式化)
支持所有 C++ 基础类型(整数、浮点数、字符、字符串、布尔值等),无需记忆占位符(对比 printf):
#include <iostream>
#include <string> // 用 string 类型需包含
using namespace std;
int main() {
// 基础类型输出
int a = 100;
double pi = 3.14159;
char c = 'A';
bool flag = true;
string str = "Hello C++"; // C++ 字符串(区别于C风格字符数组)
// 链式输出,endl 表示换行(等价于 \n + 刷新缓冲区)
cout << "整数:" << a << endl;
cout << "浮点数:" << pi << endl;
cout << "字符:" << c << endl;
cout << "布尔值:" << boolalpha << flag << endl; // boolalpha:输出 true/false(默认输出 1/0)
cout << "字符串:" << str << endl;
return 0;
}
输出结果:
plaintext
整数:100
浮点数:3.14159
字符:A
布尔值:true
字符串:Hello C++
2. 格式化输出(精度、宽度、对齐、填充)
cout 的格式化需借助 <iomanip> 头文件中的操纵符(如 setprecision、setw 等),核心格式化场景如下:
| 格式化需求 | 操纵符 / 方法 | 示例 | 效果 |
|---|---|---|---|
| 浮点数精度 | setprecision(n) + fixed | cout << fixed << setprecision(2) << 3.1415; | 保留 2 位小数(3.14) |
| 输出宽度 | setw(n) | cout << setw(5) << 123; | 占 5 个字符( 123) |
| 左对齐 | left(默认右对齐) | cout << left << setw(5) << 123; | 左对齐(123 ) |
| 填充字符 | setfill(c) | cout << setfill('0') << setw(5) << 123; | 补 0(00123) |
| 进制输出 | hex/oct/dec | cout << hex << 255; | 十六进制(ff) |
示例代码:
#include <iostream>
#include <iomanip> // 格式化操纵符头文件
using namespace std;
int main() {
double num = 123.456789;
int n = 789;
// 1. 浮点数保留2位小数(固定格式,非科学计数法)
cout << "保留2位小数:" << fixed << setprecision(2) << num << endl; // 123.46
// 2. 宽度8 + 左对齐 + 补0
cout << "宽度8+左对齐+补0:"
<< setw(8) << left << setfill('0') << n << endl; // 78900000
// 3. 十六进制输出(带前缀0x)
cout << "十六进制:" << hex << showbase << 255 << endl; // 0xff
// 重置格式化(恢复默认)
cout << resetiosflags(ios::hex | ios::showbase) << dec;
return 0;
}
3. 换行:endl vs \n
endl:换行 + 刷新输出缓冲区(fflush),高频输出时效率低(如循环打印百万行);\n:仅换行,不刷新缓冲区,效率更高,非必要场景优先用\n。
// 高效换行(推荐)
cout << "Hello\n";
// 刷新缓冲区的换行(仅需要立即输出时用,如日志)
cout << "Hello" << endl;
三、cin 核心用法(输入)
1. 基础输入(空格 / 换行分隔)
cin 用 >> 读取数据时,会自动跳过空白字符(空格、换行、制表符),直到遇到有效数据:
#include <iostream>
#include <string>
using namespace std;
int main() {
int a, b;
string name;
double score;
cout << "请输入两个整数(空格/换行分隔):";
cin >> a >> b; // 支持链式输入,自动解析整数
cout << "请输入姓名和分数:";
cin >> name >> score; // 输入示例:Tom 95.5
cout << "整数和:" << a + b << endl;
cout << "姓名:" << name << ",分数:" << score << endl;
return 0;
}
输入示例:
plaintext
请输入两个整数(空格/换行分隔):10 20
请输入姓名和分数:Tom 95.5
输出:
plaintext
整数和:30
姓名:Tom,分数:95.5
2. 读取整行输入(含空格)
cin >> 无法读取含空格的字符串(遇到空格停止),需用 getline(cin, 字符串变量):⚠️ 注意:cin >> 后接 getline 时,需先处理缓冲区残留的换行符(\n)用cin.ignore()。
#include <iostream>
#include <string>
using namespace std;
int main() {
int age;
string name, address;
cout << "请输入年龄:";
cin >> age;
// 关键:清空 cin 缓冲区的换行符(cin >> age 会留下 \n,导致 getline 直接读取空行)
cin.ignore(); // 忽略缓冲区的一个字符(即 \n)
cout << "请输入姓名(可含空格):";
getline(cin, name); // 读取整行,包括空格
cout << "请输入地址(可含空格):";
getline(cin, address);
cout << "年龄:" << age << endl;
cout << "姓名:" << name << endl;
cout << "地址:" << address << endl;
return 0;
}
输入示例:
plaintext
请输入年龄:20
请输入姓名(可含空格):Tom Smith
请输入地址(可含空格):Beijing China
输出:
plaintext
年龄:20
姓名:Tom Smith
地址:Beijing China
3. 输入错误处理
cin 读取数据失败时(如输入字符串到整数变量),会进入错误状态,后续输入全部失效,需重置状态并清空缓冲区:
#include <iostream>
using namespace std;
int main() {
int num;
cout << "请输入一个整数:";
cin >> num;
// 检查输入是否失败
if (cin.fail()) {
cout << "输入错误!请输入整数。" << endl;
// 重置错误状态
cin.clear();
// 清空缓冲区的错误数据
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} else {
cout << "你输入的整数是:" << num << endl;
}
return 0;
}
⚠️ 注意:使用 numeric_limits 需包含 <limits> 头文件。
四、cin/cout 高级优化
默认情况下,cin/cout 为了兼容 C 语言的 stdio(如 printf/scanf),会有同步开销,导致效率较低。高频输入输出场景(如算法竞赛、大数据处理)可关闭同步,大幅提升效率:
#include <iostream>
using namespace std;
int main() {
// 核心优化:关闭 cin/cout 与 C 标准流的同步
ios::sync_with_stdio(false);
// 解除 cin 与 cout 的绑定(cin 读取时不会自动刷新 cout)
cin.tie(nullptr);
// 后续 cin/cout 效率接近 scanf/printf
int a;
cin >> a;
cout << a << '\n'; // 用 \n 而非 endl,进一步提升效率
return 0;
}
五、cin/cout 常见坑点
- getline 读取空行:
cin >>后未清空换行符,导致getline直接读取空行 → 解决方案:cin.ignore()。 - 布尔值输出 1/0:默认
cout << true输出1,需加boolalpha输出true/false。 - 格式化操纵符生效范围:
setw(n)仅对下一个输出项生效,其他操纵符(如fixed、left)会持续生效,需用resetiosflags重置。 - 中文乱码(Windows):控制台编码不匹配导致乱码,解决方案:
// 设置 cout 编码为 UTF-8 cout.imbue(locale("zh_CN.UTF-8")); // 或设置控制台编码(Windows 特有) #include <windows.h> SetConsoleOutputCP(65001); // UTF-8 编码
六、总结
| 场景 | 用法要点 |
|---|---|
| 简单输出 | cout << 数据 << '\n'(优先用 \n) |
| 复杂格式化输出 | 结合 <iomanip> 操纵符(fixed/setprecision/setw/left 等) |
| 简单输入(无空格) | cin >> 变量(自动跳过空白字符) |
| 含空格的字符串输入 | getline(cin, 字符串),注意先 cin.ignore() 清空换行符 |
| 高频输入输出 | 加 ios::sync_with_stdio(false); cin.tie(nullptr); 优化效率 |
| 输入错误处理 | 用 cin.fail() 检查,cin.clear() 重置状态,cin.ignore() 清空缓冲区 |
cin/cout 是 C++ 原生的输入输出方案,核心优势是类型安全(编译期检查)和可扩展性(支持自定义类型重载),掌握格式化操纵符和输入缓冲区处理是关键,优化后效率可接近甚至媲美 C 语言的 scanf/printf。
317

被折叠的 条评论
为什么被折叠?



