-
Notifications
You must be signed in to change notification settings - Fork 1
Cpp Usage zh CN
本页面介绍 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;,因为 cin 和 cout 这类名称在和 std::cin、std::cout 一起使用时容易造成混淆。
C++ 头文件提供两种不同的文件输入输出模式:
| 模式 | 函数 | 主要使用的流 | 用途 |
|---|---|---|---|
| 标准流重定向 |
cfs::cfs,cfs::closecfs
|
std::cin,std::cout,scanf,printf
|
重定向标准输入输出 |
| 独立 C++ 文件流 |
cfs::cppfs,cfs::closecppfs
|
cfs::cin,cfs::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::cin 或 std::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() 内部会使用这些设备名称来恢复标准流。
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 传入 NULL 或 nullptr。
如果你只需要重定向输入或输出中的一边,请使用 cfs::cfs()。
如果 cfs::cin 或 cfs::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();void cfs::closecppfs();该函数会在 cfs::cin 和 cfs::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::cin 或 cfs::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()。
在本地练习信息学奥赛(OI)题目时,cfstream 可以用于方便地进行文件输入输出调试。
在本地调试时,你可以将标准输入输出重定向到文件,这样 cin、cout、scanf 和 printf 都会使用指定的文件。
这种用法仅适合在家中或本机调试时方便使用,不适用于提交到 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;
}在这个示例中:
-
cin从test.in读取 -
cout写入test.out -
scanf从test.in读取 -
printf写入test.out
因为 cfs::cfs() 重定向了标准输入输出流,所以 C++ 风格输入输出和 C 风格输入输出都会使用被重定向后的文件。
提交到在线评测系统时,除非评测平台明确允许自定义文件输入输出辅助库,否则应移除 cfstream 头文件和所有 cfstream 函数调用。
在 cfs.hpp 中,cfs::cin 和 cfs::cout 使用 static 声明。
这会让它们具有内部链接属性。
实际效果是:每个包含 cfs.hpp 的翻译单元都会拥有自己独立的一份:
cfs::cin
cfs::cout这是 cfstream 的有意设计。
这意味着不同 .cpp 文件之间不会共享同一份文件流状态。
错误写法:
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();错误写法:
cfs::cppfs(NULL, "test.out");应改用 cfs::cfs():
cfs::cfs(NULL, "test.out");或在 C++11 及更高版本中:
cfs::cfs(nullptr, "test.out");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;推荐写法:
cfs::cppfs("test.in", "test.out");
// 使用 cfs::cin 和 cfs::cout
cfs::closecppfs();虽然程序结束时文件流通常会被自动关闭,但显式关闭可以让程序行为更清晰。
closecppfs() 只会关闭 cfs::cin 和 cfs::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 使用的输出文件流 |
继续阅读: