Skip to content

C Usage zh CN

weigao edited this page Jun 21, 2026 · 2 revisions

C 用法

本页面介绍 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 后,可以使用常见的标准输入输出设施,例如 scanfprintf

基本用法

函数

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() 建立的文件重定向,并尝试将标准输入输出恢复到控制台。

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

示例:

#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,所以每个包含该头文件的翻译单元都会拥有自己内部的一份函数定义。这样可以避免在多个源文件中包含该头文件时出现外部链接冲突。

C++ 兼容性

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++ 项目中造成命名冲突。由这种用法导致的问题可能不会被官方支持。

常见错误

1. 使用低于 C99 的 C 标准

错误示例:

-std=c89

正确示例:

-std=c99

或更高版本:

-std=c11
-std=c17
-std=c23

2. 误以为 NULL 表示空文件名

NULL 不表示空文件名。

它表示对应的流不会被重定向。

示例:

cfs(NULL, "test.out");

这表示只重定向输出。

3. 忘记调用 closecfs

推荐写法:

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

/* 使用 scanf 和 printf */

closecfs();

虽然操作系统通常会在程序结束时关闭文件,但显式调用 closecfs() 可以让程序行为更清晰。

4. 误以为 closecfs 会永久关闭 stdinstdout

closecfs() 不会永久销毁 stdinstdout

它会尝试将标准输入输出恢复到控制台设备。

函数总览

函数 返回类型 说明
cfs_getversion() const char* 返回当前 cfstream 版本
cfs(input, output) void 重定向标准输入输出
closecfs() void 将标准输入输出恢复到控制台

下一页

继续阅读:

Clone this wiki locally