C++ 基本文件 I/O

C++ 的文件 I/O 与普通 I/O 工作原理非常相似,只是增加了少量细节。标准库提供了 3 个基本的文件 I/O 类:

  • ifstream(派生自 istream)——用于文件输入;
  • ofstream(派生自 ostream)——用于## 文件输出;
  • fstream(派生自 iostream)——用于文件输入/输出。

使用这些类前需包含头文件 <fstream>

coutcincerrclog 等已自动就绪的流不同,文件流必须由程序员显式建立。但过程极其简单:只需用文件名作为参数构造相应文件流对象,随后便可使用 <<>> 进行读写。使用完毕后,可显式调用 close() 关闭文件;若忽略此步骤,当文件流对象离开作用域时,其析构函数会自动关闭文件。

文件输出

下面示例使用 ofstream 向文件写入数据:

#include <fstream>
#include <iostream>

int main()
{
    // 使用 ofstream 写文件,文件名为 Sample.txt
    std::ofstream outf{ "Sample.txt" };

    // 若无法打开文件
    if (!outf)
    {
        std::cerr << "Uh oh, Sample.txt could not be opened for writing!\n";
        return 1;
    }

    // 写入两行
    outf << "This is line 1\n";
    outf << "This is line 2\n";

    return 0;
    // outf 离开作用域后,析构函数自动关闭文件
}

在项目目录下将生成 Sample.txt,用文本编辑器打开即可看到两行内容。
也可使用 put() 一次写入单个字符。

文件输入

下面读取刚才创建的文件:

#include <fstream>
#include <iostream>
#include <string>

int main()
{
    // 使用 ifstream 读文件
    std::ifstream inf{ "Sample.txt" };

    if (!inf)
    {
        std::cerr << "Uh oh, Sample.txt could not be opened for reading!\n";
        return 1;
    }

    std::string strInput{};
    while (inf >> strInput)           // 提取运算符以空白为分隔
        std::cout << strInput << '\n';

    return 0;
    // inf 离开作用域后析构,自动关闭文件
}

输出结果为:

This
is
line
1
This
is
line
2

显然,提取运算符遇到空白即分割。若想整行读取,应使用 getline()

std::string strInput{};
while (std::getline(inf, strInput))
    std::cout << strInput << '\n';

输出:

This is line 1
This is line 2

缓冲输出

C++ 的输出可能是缓冲的。数据先写入缓冲区,而非立即落盘。当缓冲区被“刷新”(flush)时,才会真正写入磁盘。关闭文件会强制刷新缓冲区并关闭文件。
若程序异常终止或显式调用 exit() 而未关闭文件,缓冲区可能未刷新,导致数据丢失。因此,在调用 exit() 前应显式关闭文件。
可手动刷新:

  • 调用 ostream::flush()
  • 向流插入 std::flush
  • 使用 std::endl(会插入换行并刷新,但频繁使用可能影响性能;性能敏感场景可用 '\n' 代替)

文件打开模式

默认情况下,若文件已存在,写操作会覆盖原有内容。如需追加,可在构造 ofstream 时指定模式:

模式标志含义
app追加模式:写入始终在文件末尾
ate打开后立即定位到文件尾
binary以二进制方式打开
in读模式(ifstream 默认)
out写模式(ofstream 默认)
trunc若文件已存在,先清空

可用按位或 | 组合多个标志。
fstream 默认使用 std::ios::in | std::ios::out;若文件不存在且仅用 in 模式,打开会失败。若需创建新文件,可仅用 out 模式。

示例:向已有文件追加两行:

#include <iostream>
#include <fstream>

int main()
{
    std::ofstream outf{ "Sample.txt", std::ios::app };

    if (!outf)
    {
        std::cerr << "Uh oh, Sample.txt could not be opened for writing!\n";
        return 1;
    }

    outf << "This is line 3\n";
    outf << "This is line 4\n";

    return 0;
}

文件内容变为:

This is line 1
This is line 2
This is line 3
This is line 4

显式打开文件(open())

同显式关闭文件一样,也可使用 open() 成员函数:

std::ofstream outf{ "Sample.txt" };
outf << "This is line 1\n";
outf << "This is line 2\n";
outf.close(); // 显式关闭

// 追加
outf.open("Sample.txt", std::ios::app);
outf << "This is line 3\n";
outf.close();

更多 open() 细节可查阅官方文档。

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"