C++ 基本输入/输出
C++ 基本输入/输出 (I/O)
Section titled “C++ 基本输入/输出 (I/O)”C++ 使用基于流(stream)的方法处理输入和输出。流是 I/O 设备(如键盘、屏幕、文件、网络连接)的抽象表示,被视为字节序列。本章涵盖使用标准流进行控制台 I/O 的基础知识。
输入操作涉及字节 从 输入设备(例如键盘)流向 内存。输出操作涉及字节 从 内存 流向 输出设备(例如显示屏)。
I/O 库头文件
Section titled “I/O 库头文件”C++ 的 I/O 功能由多个头文件提供:
| 头文件 (Header File) | 功能和描述 (Function and Description) |
|---|---|
<iostream> | 定义了核心标准 I/O 流对象:std::cin(标准输入)、std::cout(标准输出)、std::cerr(标准错误,无缓冲)和 std::clog(标准错误,缓冲)。 |
<iomanip> | 提供了用于格式化输出的流操纵符(stream manipulators)(例如,std::setw 设置字段宽度,std::setprecision 设置浮点精度,std::fixed,std::scientific)。 |
<fstream> | 声明了用于文件 I/O 的类:std::ifstream(文件输入)、std::ofstream(文件输出)、std::fstream(文件输入/输出)。 |
<sstream> | 声明了用于字符串 I/O 的类:std::istringstream(字符串输入)、std::ostringstream(字符串输出)、std::stringstream(字符串输入/输出)。对于解析和格式化字符串很有用。 |
标准输出流 (std::cout)
Section titled “标准输出流 (std::cout)”std::cout 是 ostream 类的一个预定义对象,通常连接到控制台显示器。它与流插入运算符(<<)一起使用,将数据(变量、字面值、表达式结果)发送到标准输出。
#include <iostream> // Required for std::cout, std::endl#include <string> // Recommended for using std::string
int main() { std::string message = "Hello C++ Modern I/O!"; int year = 2023;
// The << operator is overloaded for various data types. // << 运算符为各种数据类型进行了重载。 std::cout << "Message: " << message << std::endl; std::cout << "Year: " << year << std::endl; std::cout << "Next year: " << year + 1 << std::endl;
// std::endl inserts a newline character ('\n') and flushes the output buffer. // std::endl 插入换行符 ('\n') 并刷新输出缓冲区。 // '\n' alone just inserts a newline and might be slightly more performant // 仅使用 '\n' 只插入换行符,如果不需要立即刷新,性能可能会略好。 // if immediate flushing isn't needed. std::cout << "End of program.\n";
return 0;}输出:
Message: Hello C++ Modern I/O!Year: 2023Next year: 2024End of program.<< 运算符可以链式使用,以便在单个语句中输出多个项。编译器会自动确定数据类型并使用正确的 << 重载。
标准输入流 (std::cin)
Section titled “标准输入流 (std::cin)”std::cin 是 istream 类的一个预定义对象,通常连接到键盘。它与流提取运算符(>>)一起使用,从标准输入读取数据并将其存储到变量中。
#include <iostream>#include <string>#include <limits> // Required for std::numeric_limits // 用于 std::numeric_limits
int main() { std::string name; int age;
std::cout << "Please enter your first name: "; std::cin >> name; // Reads input until whitespace is encountered // 读取输入直到遇到空白字符
std::cout << "Please enter your age: "; std::cin >> age;
// Check if input failed (e.g., user entered text for age) // 检查输入是否失败(例如,用户为年龄输入了文本) if (std::cin.fail()) { std::cerr << "Error: Invalid input for age.\n"; // 错误:年龄输入无效。 // Clear the error state // 清除错误状态 std::cin.clear(); // Ignore the rest of the invalid input line // 忽略输入行中其余的无效内容 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); return 1; // Indicate error // 指示错误 }
std::cout << "Hello, " << name << "! You are " << age << " years old." << std::endl;
// Consume the leftover newline character from the previous input // 消耗掉之前输入留下的换行符 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::string fullName; std::cout << "Please enter your full name: "; // Use std::getline to read the entire line, including spaces // 使用 std::getline 读取整行,包括空格 std::getline(std::cin, fullName); std::cout << "Your full name is: " << fullName << std::endl;
return 0;}示例交互:
Please enter your first name: AlicePlease enter your age: 30Hello, Alice! You are 30 years old.Please enter your full name: Alice WonderlandYour full name is: Alice Wonderlandstd::cin 的关键点:
>>运算符通常会跳过前导空白字符(如空格、制表符)并在第一个尾随空白字符(空格、制表符、换行符)处停止读取。- 要读取整行内容(包括空格),请使用
std::getline(std::cin, your_string_variable);。 - 如果用户输入了不兼容类型的数据(例如,在期望数字时输入文本),输入可能会失败。在输入操作后,始终检查
std::cin的状态(例如,使用std::cin.fail()或在布尔上下文检查流,如if (std::cin >> age)),并适当地处理错误。 - 混合使用
>>和std::getline需要小心,因为>>通常会在输入缓冲区中留下换行符(\n),紧随其后的std::getline会立即消耗掉它,导致意外的空输入。在>>之后调用std::getline之前,使用std::cin.ignore()丢弃剩余字符,特别是换行符。
标准错误流 (std::cerr)
Section titled “标准错误流 (std::cerr)”std::cerr 是一个 ostream 对象,通常连接到控制台显示器,专门用于错误消息。它是无缓冲的(unbuffered),这意味着发送到 std::cerr 的输出会立即被刷新(显示)。这确保了即使程序随后崩溃,错误消息也能及时出现。
#include <iostream>#include <fstream>#include <string>
int main() { std::string filename = "nonexistent_file.txt"; std::ifstream infile(filename);
if (!infile.is_open()) { // Use cerr for error messages // 使用 cerr 输出错误消息 std::cerr << "Error: Failed to open file '" << filename << "'" << std::endl; return 1; // Indicate failure // 指示失败 }
// ... process file ... // ... 处理文件 ... infile.close(); return 0;}输出(如果文件不存在):
Error: Failed to open file 'nonexistent_file.txt'标准日志流 (std::clog)
Section titled “标准日志流 (std::clog)”std::clog 是另一个 ostream 对象,也通常连接到控制台,用于记录信息。与 std::cerr 不同,std::clog 是缓冲的(buffered)。输出可能会被保存在缓冲区中,只有当缓冲区满、手动刷新或程序正常结束时才会被写入。这对于频繁的日志消息来说比无缓冲输出更高效。
#include <iostream>
int main() { // Use clog for general logging or progress messages // 使用 clog 输出通用日志或进度消息 std::clog << "Log: Program starting initialization phase." << std::endl; // ... some operations ... // ... 一些操作 ... std::clog << "Log: Initialization complete." << std::endl; return 0;}使用 std::cout 用于正常的程序输出,std::cerr 用于错误,std::clog 用于日志/状态消息。这种分离允许用户在需要时独立重定向这些流(例如,将错误重定向到单独的文件)。