Skip to content

流的状态与错误处理 ​

每个 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 析构,缓冲区自动刷新,文件关闭