流的状态与错误处理
每个 C++ 流对象都有状态标志,用于指示流的质量和错误情况。
流状态标志
| 状态标志 | 含义 |
|---|---|
goodbit | 流处于正常状态,无错误 |
eofbit | 已到达文件末尾(EOF) |
failbit | 上次 I/O 操作失败(如类型不匹配) |
badbit | 流发生严重错误(如硬件故障) |
检查流状态
cpp
#include <iostream>
#include <sstream>
int main() {
std::stringstream ss("hello");
// 方式1:使用成员函数
std::cout << "good: " << ss.good() << std::endl; // 1 (true)
std::cout << "eof: " << ss.eof() << std::endl; // 0
std::cout << "fail: " << ss.fail() << std::endl; // 0
std::cout << "bad: " << ss.bad() << std::endl; // 0
// 方式2:转换为 bool(检查 failbit 或 badbit)
int num;
ss >> num; // 尝试读取整数到字符串 "hello"
if (!ss) {
std::cout << "读取失败!" << std::endl;
}
// 方式3:使用 rdstate()
std::cout << "state: " << ss.rdstate() << std::endl;
return 0;
}常见错误处理
输入类型不匹配
cpp
#include <iostream>
#include <string>
int main() {
std::string input = "abc";
int num;
std::stringstream ss(input);
ss >> num; // 失败:无法将 "abc" 转换为整数
if (ss.fail()) {
std::cout << "输入类型不匹配!" << std::endl;
ss.clear(); // 清除失败状态
ss.str(""); // 清空内容
ss << "123"; // 重新填充
ss >> num; // 成功
std::cout << "num = " << num << std::endl; // 123
}
return 0;
}到达文件末尾
cpp
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream file("test.txt");
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
// 读取结束后,检查状态
if (file.eof()) {
std::cout << "已到达文件末尾" << std::endl;
} else if (file.fail()) {
std::cout << "读取失败" << std::endl;
}
file.close();
return 0;
}综合:带错误处理的完整示例
cpp
#include <iostream>
#include <fstream>
#include <string>
bool readInt(std::istream& in, int& value) {
if (!(in >> value)) {
in.clear(); // 清除错误状态
in.ignore(1000, '\n'); // 跳过错误输入
return false;
}
return true;
}
int main() {
int num;
std::cout << "请输入一个整数: ";
if (readInt(std::cin, num)) {
std::cout << "读取成功: " << num << std::endl;
} else {
std::cout << "输入无效,请输入整数!" << std::endl;
}
return 0;
}流刷新与同步
flush - 强制刷新缓冲区
cpp
#include <fstream>
std::ofstream out("log.txt");
out << "开始记录...";
out.flush(); // 立即写入文件,确保数据不丢失
out << "错误发生";
out.flush();什么时候会自动刷新
- 流对象析构时
- 调用
endl、ends、flush时 - 当缓冲区满时
- 读取输入时(关联的输出流)
关闭流时自动刷新
cpp
{
std::ofstream out("file.txt");
out << "数据";
} // out 析构,缓冲区自动刷新,文件关闭