Skip to content

Cpp Usage zh CN

weigao edited this page Jun 20, 2026 · 1 revision

C++ 用法

本页面介绍 cfstream 的 C++ 接口,也就是 cfs.hpp 提供的功能。

如果你想详细了解 C++ 版本的使用方式,包括标准流重定向、独立 C++ 文件流、版本查询、关闭行为和常见使用规则,可以阅读本页面。

头文件

C++ 项目请使用:

#include "cfs.hpp"

cfs.hpp 中的所有 C++ 功能都位于 cfs 命名空间中。

cfs::cfs(...);
cfs::closecfs();

cfs::cppfs(...);
cfs::closecppfs();

cfs::cin;
cfs::cout;

cfs::getversion();

环境要求

cfs.hpp 支持:

  • C++98 或更高版本

该头文件内部已经包含所需的标准库头文件:

#include <fstream>
#include <cstdio>
#include <iostream>

因此,在很多简单程序中,只包含 cfs.hpp 就已经足够。

命名空间

所有 C++ 接口都位于 cfs 命名空间中。

示例:

#include "cfs.hpp"

int main() {
    cfs::cppfs("test.in", "test.out");

    int n;
    cfs::cin >> n;
    cfs::cout << n << '\n';

    cfs::closecppfs();
    return 0;
}

你也可以使用 using 导入部分名称,但这不是必须的。

#include "cfs.hpp"

using cfs::cppfs;
using cfs::closecppfs;
using cfs::cin;
using cfs::cout;

int main() {
    cppfs("test.in", "test.out");

    int n;
    cin >> n;
    cout << n << '\n';

    closecppfs();
    return 0;
}

在较大的项目中,不建议使用 using namespace cfs;,因为 cincout 这类名称在和 std::cinstd::cout 一起使用时容易造成混淆。

两种 C++ 使用模式

C++ 头文件提供两种不同的文件输入输出模式:

模式 函数 主要使用的流 用途
标准流重定向 cfs::cfscfs::closecfs std::cinstd::coutscanfprintf 重定向标准输入输出
独立 C++ 文件流 cfs::cppfscfs::closecppfs cfs::cincfs::cout 使用独立文件流,不改变标准流

这两种模式不同,不应混淆。

模式一:标准流重定向

函数

void cfs::cfs(const char* input, const char* output);

该函数用于重定向标准输入和/或标准输出。

其内部使用 freopen 实现。

基本示例

#include <iostream>
#include "cfs.hpp"

int main() {
    cfs::cfs("test.in", "test.out");

    int n;
    std::cin >> n;
    std::cout << n << '\n';

    cfs::closecfs();
    return 0;
}

这个程序会:

  • test.in 读取数据
  • test.out 写入数据

哪些内容会被重定向

调用:

cfs::cfs("test.in", "test.out");

之后,以下标准流或函数会受到影响:

std::cin
std::cout
scanf
printf

它们都会使用被重定向后的标准输入输出流。

只重定向输入

#include <iostream>
#include "cfs.hpp"

int main() {
    cfs::cfs("test.in", NULL);

    int n;
    std::cin >> n;
    std::cout << n << '\n';

    cfs::closecfs();
    return 0;
}

此时输入会从 test.in 读取,而输出仍然发送到控制台。

如果你使用的是 C++11 或更高版本,也可以使用 nullptr

cfs::cfs("test.in", nullptr);

只重定向输出

#include <iostream>
#include "cfs.hpp"

int main() {
    cfs::cfs(NULL, "test.out");

    int n;
    std::cin >> n;
    std::cout << n << '\n';

    cfs::closecfs();
    return 0;
}

此时输入仍然来自控制台,而输出会写入 test.out

如果你使用的是 C++11 或更高版本,也可以使用 nullptr

cfs::cfs(nullptr, "test.out");

不进行重定向

两个参数都可以传入 NULL

cfs::cfs(NULL, NULL);

在 C++11 或更高版本中:

cfs::cfs(nullptr, nullptr);

这种写法是允许的,但没有实际意义。

关闭文件重定向并恢复控制台流

函数

void cfs::closecfs();

该函数用于结束由 cfs::cfs() 建立的文件重定向,并尝试将标准输入输出恢复到控制台。

它并不是永久关闭 std::cinstd::cout 本身,而是将标准流重新定向回控制台设备。

示例:

#include <iostream>
#include "cfs.hpp"

int main() {
    cfs::cfs("test.in", "test.out");

    int n;
    std::cin >> n;
    std::cout << n << '\n';

    cfs::closecfs();

    std::cout << "Back to console" << '\n';
    return 0;
}

不同平台使用的控制台设备如下:

平台 控制台设备
Windows CON
Linux / macOS / 其他类 Unix 系统 /dev/tty

closecfs() 内部会使用这些设备名称来恢复标准流。

模式二:独立 C++ 文件流

函数

void cfs::cppfs(const char* input, const char* output);

该函数会打开两个独立的 C++ 文件流:

cfs::cin
cfs::cout

它们和下面这些标准流是分开的:

std::cin
std::cout

基本示例

#include <iostream>
#include "cfs.hpp"

int main() {
    cfs::cppfs("test.in", "test.out");

    int n;
    cfs::cin >> n;
    cfs::cout << n << '\n';

    std::cout << "This goes to the console." << '\n';

    cfs::closecppfs();
    return 0;
}

这个程序会:

  • test.in 读取 n
  • n 写入 test.out
  • 通过 std::cout 将提示信息输出到控制台

文件流对象

cfs.hpp 定义了:

static std::ifstream cfs::cin;
static std::ofstream cfs::cout;

因为它们是文件流:

  • cfs::cin 的行为类似 std::ifstream
  • cfs::cout 的行为类似 std::ofstream

示例:

int x;
double y;
std::string s;

cfs::cin >> x >> y >> s;
cfs::cout << x << ' ' << y << ' ' << s << '\n';

与标准流重定向的重要区别

cfs::cppfs() 不会重定向标准流。

也就是说,下面这些不会受到影响:

std::cin
std::cout
scanf
printf

只有下面两个对象会使用由 cfs::cppfs() 打开的文件:

cfs::cin
cfs::cout

文件名必须有效

对于 cfs::cppfs,两个参数都应该是有效的文件名。

推荐写法:

cfs::cppfs("test.in", "test.out");

不要向 cfs::cppfs 传入 NULLnullptr

如果你只需要重定向输入或输出中的一边,请使用 cfs::cfs()

防止重复打开

如果 cfs::cincfs::cout 已经处于打开状态,再次调用 cfs::cppfs() 不会重新打开文件流。

示例:

cfs::cppfs("a.in", "a.out");
cfs::cppfs("b.in", "b.out");

第二次调用会输出错误信息:

Error-from-cfs Already open cppfs,please close first!

正确写法:

cfs::cppfs("a.in", "a.out");
cfs::closecppfs();

cfs::cppfs("b.in", "b.out");
cfs::closecppfs();

关闭独立 C++ 文件流

函数

void cfs::closecppfs();

该函数会在 cfs::cincfs::cout 已打开时关闭它们。

示例:

#include "cfs.hpp"

int main() {
    cfs::cppfs("test.in", "test.out");

    int n;
    cfs::cin >> n;
    cfs::cout << n << '\n';

    cfs::closecppfs();
    return 0;
}

调用 cfs::closecppfs() 后,除非再次调用 cfs::cppfs(),否则不要继续使用 cfs::cincfs::cout

版本查询

函数

const char* cfs::getversion();

该函数会以 const char* 的形式返回当前 cfstream 版本。

示例:

#include <iostream>
#include "cfs.hpp"

int main() {
    std::cout << cfs::getversion() << '\n';
    return 0;
}

对于版本 1.3.0,输出为:

1.3.0

推荐使用方式

对于大多数 C++ 程序,尤其是算法竞赛练习或本地测试,推荐使用:

#include "cfs.hpp"

int main() {
    cfs::cppfs("test.in", "test.out");

    int n;
    cfs::cin >> n;
    cfs::cout << n << '\n';

    cfs::closecppfs();
    return 0;
}

这种写法可以让文件输入输出和控制台输入输出保持分离。

只有在你想要类似 freopen 的行为时,才建议使用 cfs::cfs()

将 cfstream 用于本地 OI 调试

在本地练习信息学奥赛(OI)题目时,cfstream 可以用于方便地进行文件输入输出调试。

在本地调试时,你可以将标准输入输出重定向到文件,这样 cincoutscanfprintf 都会使用指定的文件。

这种用法仅适合在家中或本机调试时方便使用,不适用于提交到 OI 在线评测系统或正式比赛评测机。

示例:

#include <bits/stdc++.h>
#include "cfs.hpp"

using namespace std;

#define int long long
#define endl '\n'

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cfs::cfs("test.in", "test.out");

    int n;
    cin >> n;
    cout << n << endl;

    int m;
    scanf("%lld", &m);
    printf("%lld\n", m);

    cfs::closecfs();
    return 0;
}

在这个示例中:

  • cintest.in 读取
  • cout 写入 test.out
  • scanftest.in 读取
  • printf 写入 test.out

因为 cfs::cfs() 重定向了标准输入输出流,所以 C++ 风格输入输出和 C 风格输入输出都会使用被重定向后的文件。

提交到在线评测系统时,除非评测平台明确允许自定义文件输入输出辅助库,否则应移除 cfstream 头文件和所有 cfstream 函数调用。

多源文件

cfs.hpp 中,cfs::cincfs::cout 使用 static 声明。

这会让它们具有内部链接属性。

实际效果是:每个包含 cfs.hpp 的翻译单元都会拥有自己独立的一份:

cfs::cin
cfs::cout

这是 cfstream 的有意设计。

这意味着不同 .cpp 文件之间不会共享同一份文件流状态。

常见错误

1. 未关闭就重复调用 cppfs

错误写法:

cfs::cppfs("a.in", "a.out");
cfs::cppfs("b.in", "b.out");

正确写法:

cfs::cppfs("a.in", "a.out");
cfs::closecppfs();

cfs::cppfs("b.in", "b.out");
cfs::closecppfs();

2. 向 cppfs 传入 NULLnullptr

错误写法:

cfs::cppfs(NULL, "test.out");

应改用 cfs::cfs()

cfs::cfs(NULL, "test.out");

或在 C++11 及更高版本中:

cfs::cfs(nullptr, "test.out");

3. 混淆 std::cincfs::cin

cfs::cppfs() 打开的是 cfs::cin,不是 std::cin

错误写法:

cfs::cppfs("test.in", "test.out");

int n;
std::cin >> n;

正确写法:

cfs::cppfs("test.in", "test.out");

int n;
cfs::cin >> n;

4. 忘记关闭文件流

推荐写法:

cfs::cppfs("test.in", "test.out");

// 使用 cfs::cin 和 cfs::cout

cfs::closecppfs();

虽然程序结束时文件流通常会被自动关闭,但显式关闭可以让程序行为更清晰。

5. 误以为 closecppfs 会恢复 std::cinstd::cout

closecppfs() 只会关闭 cfs::cincfs::cout

它不会影响标准流。

如果使用的是标准流重定向,应调用:

cfs::closecfs();

函数总览

函数 / 对象 类型 说明
cfs::getversion() 函数 返回当前 cfstream 版本
cfs::cfs(input, output) 函数 重定向标准输入输出
cfs::closecfs() 函数 将标准输入输出恢复到控制台
cfs::cppfs(input, output) 函数 打开独立 C++ 文件流
cfs::closecppfs() 函数 关闭独立 C++ 文件流
cfs::cin std::ifstream cppfs 使用的输入文件流
cfs::cout std::ofstream cppfs 使用的输出文件流

下一页

继续阅读:

Clone this wiki locally