C++ 的输入输出(I/O)主要通过标准库中的流对象实现,核心是对“数据流”的操作。其语法规则围绕“流对象”“操作符”和“数据类型匹配”展开,以下从标准 I/O(控制台) 和文件 I/O 两部分详细说明。
一、标准输入输出(控制台 I/O)
标准 I/O 用于程序与用户通过键盘/屏幕交互,核心依赖 <iostream>
头文件中的三个流对象:
cout
:标准输出流(对应屏幕)cin
:标准输入流(对应键盘)cerr
/clog
:标准错误流(用于输出错误信息,cerr
不缓冲,clog
缓冲)
1. 输出操作(cout
)
基本语法
通过 <<
(输出流操作符) 向 cout
流中“插入”数据,格式:
cout << 数据1 << 数据2 << ... << 操纵符;
- 数据:可以是常量、变量、表达式(支持基本类型:
int
/double
/string
等)。 - 操纵符:用于控制输出格式(如换行、刷新缓冲区等)。
示例与规则
#include <iostream> // 必须包含的头文件
#include <string> // 使用 string 类型需包含using namespace std; // 简化代码,否则需写 std::coutint main() {// 1. 输出常量cout << "Hello World"; // 输出字符串常量cout << 123; // 输出整数常量cout << 3.14; // 输出浮点数常量// 2. 输出变量int age = 20;string name = "Alice";cout << name << " is " << age << " years old"; // 链式输出变量和常量// 3. 控制输出格式(常用操纵符)cout << endl; // 换行 + 刷新缓冲区(等价于 "\n" + 刷新)cout << "Line 1\nLine 2"; // \n 仅换行,不刷新cout << flush; // 强制刷新缓冲区(不换行)return 0;
}
核心规则
- 链式输出:
<<
操作符返回流对象本身(cout
),因此可连续拼接多个输出项。 - 自动类型转换:
cout
会根据数据类型自动转为字符串输出(无需手动转换,如直接输出int
/double
)。 - 操纵符作用:
endl
:换行 + 刷新缓冲区(确保数据立即显示)。\n
:仅换行(效率更高,适合大量输出)。flush
:仅刷新缓冲区(无换行)。
2. 输入操作(cin
)
基本语法
通过 >>
(输入流操作符) 从 cin
流中“提取”数据到变量,格式:
cin >> 变量1 >> 变量2 >> ...;
- 变量:必须是已声明的变量(需指定类型,如
int
/string
等)。
示例与规则
#include <iostream>
#include <string>using namespace std;int main() {// 1. 输入单个变量int num;cout << "请输入一个整数:";cin >> num; // 从键盘读取整数到 num// 2. 连续输入多个变量(空格/换行分隔)string name;int age;cout << "请输入姓名和年龄:";cin >> name >> age; // 输入 "Alice 20" → name="Alice", age=20// 3. 处理输入失败(如输入类型不匹配)if (cin.fail()) { // 输入失败(如预期 int 却输入字符串)cout << "输入格式错误!" << endl;cin.clear(); // 清除错误状态// 忽略缓冲区中剩余的错误数据cin.ignore(numeric_limits<streamsize>::max(), '\n');}return 0;
}
核心规则
- 分隔符:
cin
以空白字符(空格、Tab、换行)作为输入项的分隔符,自动跳过空白。 - 类型匹配:输入的数据类型必须与变量类型一致,否则会触发输入失败(需用
cin.fail()
检测)。 - 缓冲区机制:输入数据先存到缓冲区,
>>
从缓冲区提取数据,若缓冲区为空则等待用户输入。 - 读取字符串限制:
cin >> string
只能读取到第一个空白字符(如需读取整行,需用getline
)。
3. 读取整行输入(getline
)
当需要读取包含空格的完整行(如句子)时,使用 getline
函数:
#include <iostream>
#include <string>using namespace std;int main() {string line;cout << "请输入一行文字:";getline(cin, line); // 读取整行(包括空格)到 linecout << "你输入的是:" << line << endl;return 0;
}
注意事项
getline
会读取换行符\n
之前的所有字符,并自动丢弃换行符(不存入变量)。- 若之前用
cin >>
读取过数据,缓冲区可能残留换行符,导致getline
直接读取空行,需先清除:int num; cin >> num; cin.ignore(); // 忽略缓冲区中残留的换行符 string line; getline(cin, line); // 正常读取一行
二、文件输入输出(文件 I/O)
文件 I/O 用于读写磁盘文件,核心依赖 <fstream>
头文件中的三个流类:
ifstream
:输入文件流(读文件)ofstream
:输出文件流(写文件)fstream
:可同时读写的文件流
1. 打开文件的方式
通过流对象的 open
方法或构造函数打开文件,需指定文件路径和打开模式:
#include <fstream>
#include <iostream>using namespace std;int main() {// 方式1:通过构造函数打开ofstream outFile("output.txt", ios::out); // 输出模式(默认,覆盖写入)// 方式2:通过 open 方法打开ifstream inFile;inFile.open("input.txt", ios::in); // 输入模式(默认,只读)// 检查文件是否打开成功if (!inFile.is_open()) {cerr << "文件打开失败!" << endl;return 1;}// 操作文件...// 关闭文件(析构函数会自动关闭,但手动关闭更规范)inFile.close();outFile.close();return 0;
}
常用打开模式
模式 | 含义 | 适用流 |
---|---|---|
ios::in |
只读方式打开(默认 for ifstream) | ifstream |
ios::out |
只写方式打开(默认 for ofstream),覆盖原有内容 | ofstream |
ios::app |
追加模式(在文件末尾写入) | ofstream |
ios::binary |
二进制模式(默认是文本模式) | 所有文件流 |
ios::trunc |
若文件存在则清空(与 ios::out 结合) |
ofstream |
ios::ate |
打开后定位到文件末尾 | fstream |
模式可组合使用(用 |
连接),例如 ios::out | ios::binary
表示二进制写模式。
2. 读文件(ifstream
)
基本用法
与 cin
类似,通过 >>
或 getline
读取文件内容:
#include <fstream>
#include <iostream>
#include <string>using namespace std;int main() {ifstream inFile("input.txt");if (!inFile) { // 等价于 !inFile.is_open()cerr << "文件打开失败!" << endl;return 1;}// 方法1:用 >> 读取(以空白分隔)int num;inFile >> num; // 从文件读整数// 方法2:用 getline 读取整行string line;while (getline(inFile, line)) { // 循环读每行,直到文件结束cout << line << endl;}// 检查是否到文件末尾(而非错误)if (inFile.eof()) {cout << "文件读取完毕" << endl;}inFile.close();return 0;
}
3. 写文件(ofstream
)
基本用法
与 cout
类似,通过 <<
写入数据到文件:
#include <fstream>
#include <string>using namespace std;int main() {// 覆盖写入(默认 ios::out)ofstream outFile("output.txt");// 追加写入:ofstream outFile("output.txt", ios::app);if (!outFile) {cerr << "文件打开失败!" << endl;return 1;}// 写入数据outFile << "Hello File" << endl; // 写入字符串+换行int age = 20;outFile << "Age: " << age << endl; // 写入变量outFile.close();return 0;
}
三、输入输出的格式控制
C++ 提供了多种方式控制 I/O 格式(如对齐、精度、进制等),常用两种方式:
1. 操纵符(iomanip
头文件)
通过操纵符直接在流中设置格式:
#include <iostream>
#include <iomanip> // 需包含此头文件using namespace std;int main() {double pi = 3.1415926535;// 控制浮点数精度(保留 2 位小数)cout << fixed << setprecision(2) << pi << endl; // 输出:3.14// 控制整数进制(十进制、八进制、十六进制)int num = 255;cout << dec << num << endl; // 十进制(默认):255cout << oct << num << endl; // 八进制:377cout << hex << num << endl; // 十六进制:ff// 控制宽度和对齐(右对齐,宽度 10)cout << setw(10) << "Name" << setw(5) << "Age" << endl;cout << setw(10) << "Alice" << setw(5) << 20 << endl;return 0;
}
常用操纵符:
fixed
+setprecision(n)
:控制浮点数小数位数(n
位)。setw(n)
:设置输出宽度(仅对下一个输出项有效)。left
/right
:左对齐/右对齐(配合setw
使用)。dec
/oct
/hex
:设置整数为十进制/八进制/十六进制。
2. 成员函数(流对象的方法)
通过流对象的成员函数设置格式(更灵活,可重复使用):
#include <iostream>using namespace std;int main() {double pi = 3.1415926535;// 设置精度(等价于 fixed + setprecision(2))cout.precision(2);cout << fixed;cout << pi << endl; // 输出:3.14// 设置宽度和对齐cout.width(10); // 宽度 10cout << left; // 左对齐cout << "Alice" << endl; // 输出:Alice // (Alice 后补 5 个空格,凑满 10 宽度)return 0;
}
四、核心规则总结
- 流对象是核心:所有 I/O 操作围绕
cout
/cin
(控制台)或ifstream
/ofstream
(文件)展开。 - 操作符含义:
<<
用于输出(插入到流),>>
用于输入(从流提取),支持链式操作。 - 类型必须匹配:输入时,变量类型需与输入数据类型一致,否则会触发错误。
- 缓冲区机制:I/O 数据先存于缓冲区,
endl
或flush
可强制刷新(立即显示/写入)。 - 文件操作步骤:打开文件 → 检查是否成功 → 读写数据 → 关闭文件(或依赖析构自动关闭)。
掌握这些规则后,就能灵活处理 C++ 中的各种输入输出场景,包括控制台交互和文件读写。