输入关键词开始搜索

C++ IO 流 — 文件与字符串流

三个标准流

#include <iostream>   // cin cout cerr clog
#include <fstream>    // ifstream ofstream fstream
#include <sstream>    // istringstream ostringstream stringstream

文件读写

#include <fstream>

// 写文件
std::ofstream out("data.txt");
if (!out) { cerr << "无法打开文件\n"; return; }
out << "Hello, " << 42 << '\n';
out.close();  // 显式关闭(析构也会关)

// 读文件 — 逐行
std::ifstream in("data.txt");
std::string line;
while (std::getline(in, line)) {
    cout << line << '\n';
}

// 读文件 — 逐词
std::string word;
while (in >> word) { /* ... */ }

// 读整个文件到 string
std::ostringstream buf;
buf << in.rdbuf();
std::string content = buf.str();

打开模式

// ios::in      读
// ios::out     写(覆盖)
// ios::app     追加
// ios::ate     打开后定位到末尾
// ios::binary  二进制模式
// ios::trunc   清空已有内容(out 默认)

// 追加写
std::ofstream log("app.log", std::ios::app);
log << "new entry\n";

// 二进制写
std::ofstream bin("data.bin", std::ios::binary);
int arr[] = {1, 2, 3, 4};
bin.write(reinterpret_cast<const char *>(arr), sizeof(arr));

// 二进制读
std::ifstream binIn("data.bin", std::ios::binary);
int buf[4];
binIn.read(reinterpret_cast<char *>(buf), sizeof(buf));
auto bytesRead = binIn.gcount();  // 实际读取字节数

字符串流

// ostringstream — 拼接字符串(效率优于 +)
std::ostringstream oss;
oss << "ID: " << id << ", Name: " << name;
std::string result = oss.str();

// istringstream — 解析字符串
std::istringstream iss("123 45.6 hello");
int a; double b; std::string c;
iss >> a >> b >> c;  // a=123, b=45.6, c="hello"

// stringstream — 读写
std::stringstream ss;
ss << 3.14;
double d;
ss >> d;  // 3.14

格式化控制

#include <iomanip>

// 精度
cout << std::fixed << std::setprecision(2) << 3.14159;  // 3.14

// 宽度 + 填充
cout << std::setw(10) << std::setfill('-') << 42;       // "--------42"

// 进制
cout << std::hex << 255;      // ff
cout << std::oct << 8;        // 10
cout << std::dec << 0xff;     // 255

// bool
cout << std::boolalpha << true;  // "true"(不是 1)

// 保存/恢复状态
auto oldFlags = cout.flags();
cout << std::hex << 255;
cout.flags(oldFlags);  // 恢复

错误状态

std::ifstream in("file.txt");

if (in.good())    { /* 没有错误 */ }
if (in.eof())     { /* 到达文件尾 */ }
if (in.fail())    { /* 逻辑错误(如格式不匹配) */ }
if (in.bad())     { /* 严重错误(如磁盘损坏) */ }

// 清除错误状态(才能继续操作)
in.clear();

// 异常模式(失败时抛异常)
in.exceptions(std::ios::failbit | std::ios::badbit);

二进制文件的序列化

// 写入结构体
struct Record {
    int32_t id;
    double value;
    char name[32];
};

Record r{1, 3.14, "test"};
std::ofstream out("record.bin", std::ios::binary);
out.write(reinterpret_cast<const char *>(&r), sizeof(r));

// ⚠️ 直接写结构体的问题:
// - 字节序(大小端)
// - 对齐填充(不同编译器可能不同)
// - 跨平台不可移植

// ✅ 推荐:逐字段写入或使用序列化库
void writeInt32(std::ostream &os, int32_t val) {
    // 网络字节序(大端)
    val = htonl(val);
    os.write(reinterpret_cast<const char *>(&val), 4);
}

性能

// ❌ endl 每次都 flush → 慢
for (int i = 0; i < 100000; ++i)
    cout << i << endl;

// ✅ '\n' 不 flush
for (int i = 0; i < 100000; ++i)
    cout << i << '\n';

// ✅ 解除与 C stdio 的同步 → 加速 3-5x
ios::sync_with_stdio(false);
cin.tie(nullptr);  // 解绑 cin 和 cout