-
Notifications
You must be signed in to change notification settings - Fork 1
C Usage zh CN
本页面介绍 cfstream 的 C 接口,也就是 cfs.h 提供的功能。
如果你想详细了解 C 版本的使用方式,包括标准流重定向、版本查询、关闭行为和常见使用规则,可以阅读本页面。
C 项目请使用:
#include "cfs.h"C 接口提供以下函数:
cfs(...);
closecfs();
cfs_getversion();与 C++ 版本不同,C 版本不使用命名空间。
cfs.h 要求:
- C99 或更高版本
如果该文件以 C 语言方式编译,并且 C 标准低于 C99,编译会被终止,并显示:
cfs.h requires C99 or later.
这个检查通过 #error 实现。
cfs.h 内部包含:
#include <stdio.h>这意味着在包含 cfs.h 后,可以使用常见的标准输入输出设施,例如 scanf、printf。
void cfs(const char* input, const char* output);该函数用于重定向标准输入和/或标准输出。
其内部使用 freopen 实现。
#include "cfs.h"
int main(void) {
cfs("test.in", "test.out");
int n;
scanf("%d", &n);
printf("%d\n", n);
closecfs();
return 0;
}这个程序会:
- 从
test.in读取数据 - 向
test.out写入数据
调用:
cfs("test.in", "test.out");之后,以下标准输入输出函数会受到影响:
scanf
printf它们会使用被重定向后的标准输入输出流。
你可以将输出文件名传入 NULL。
#include "cfs.h"
int main(void) {
cfs("test.in", NULL);
int n;
scanf("%d", &n);
printf("%d\n", n);
closecfs();
return 0;
}在这个例子中:
- 输入会从
test.in读取 - 输出仍然发送到控制台
你可以将输入文件名传入 NULL。
#include "cfs.h"
int main(void) {
cfs(NULL, "test.out");
int n;
scanf("%d", &n);
printf("%d\n", n);
closecfs();
return 0;
}在这个例子中:
- 输入仍然来自控制台
- 输出会写入
test.out
两个参数都可以传入 NULL。
cfs(NULL, NULL);这种写法是允许的,但没有实际意义。
void closecfs(void);该函数用于结束由 cfs() 建立的文件重定向,并尝试将标准输入输出恢复到控制台。
它并不是永久关闭 stdin 或 stdout 本身,而是将标准流重新定向回控制台设备。
示例:
#include "cfs.h"
int main(void) {
cfs("test.in", "test.out");
int n;
scanf("%d", &n);
printf("%d\n", n);
closecfs();
printf("Back to console\n");
return 0;
}不同平台使用的控制台设备如下:
| 平台 | 控制台设备 |
|---|---|
| Windows | CON |
| Linux / macOS / 其他类 Unix 系统 | /dev/tty |
closecfs() 内部会使用这些设备名称来恢复标准流。
const char* cfs_getversion(void);该函数会以 const char* 的形式返回当前 cfstream 版本。
示例:
#include "cfs.h"
int main(void) {
printf("%s\n", cfs_getversion());
return 0;
}对于版本 1.3.0,输出为:
1.3.0
在 cfs.h 中,函数使用 static inline 定义。
示例:
static inline void cfs(const char* input, const char* output);
static inline void closecfs(void);
static inline const char* cfs_getversion(void);这种设计使得该头文件可以直接包含在 C 项目中,不需要额外提供 .c 实现文件。
因为这些函数带有 static,所以每个包含该头文件的翻译单元都会拥有自己内部的一份函数定义。这样可以避免在多个源文件中包含该头文件时出现外部链接冲突。
当 cfs.h 被 C++ 编译器包含时,它会使用 extern "C":
#ifdef __cplusplus
extern "C" {
#endif这允许 C++ 代码包含该 C 头文件时,C 接口不会受到 C++ 名字修饰的影响。
不过,对于正常的 C++ 项目,更推荐使用:
#include "cfs.hpp"cfs.h 主要用于 C 项目。
提示: 在 C++ 中,如果你想在不使用
cfs命名空间的情况下使用 cfstream,确实可以包含cfs.h。不过,这种用法不推荐。C 头文件只提供类似于cfs.hpp中标准流重定向的功能,并且由于它不使用命名空间,可能会在 C++ 项目中造成命名冲突。由这种用法导致的问题可能不会被官方支持。
错误示例:
-std=c89
正确示例:
-std=c99
或更高版本:
-std=c11
-std=c17
-std=c23
NULL 不表示空文件名。
它表示对应的流不会被重定向。
示例:
cfs(NULL, "test.out");这表示只重定向输出。
推荐写法:
cfs("test.in", "test.out");
/* 使用 scanf 和 printf */
closecfs();虽然操作系统通常会在程序结束时关闭文件,但显式调用 closecfs() 可以让程序行为更清晰。
closecfs() 不会永久销毁 stdin 或 stdout。
它会尝试将标准输入输出恢复到控制台设备。
| 函数 | 返回类型 | 说明 |
|---|---|---|
cfs_getversion() |
const char* |
返回当前 cfstream 版本 |
cfs(input, output) |
void |
重定向标准输入输出 |
closecfs() |
void |
将标准输入输出恢复到控制台 |
继续阅读: