ZetCode

C freopen 函数

最后修改日期:2025 年 4 月 6 日

流重定向是 C 编程中一项强大的技术,它允许您更改标准流的目标。freopen 函数实现了这种重定向,在文件处理方面提供了灵活性。本教程将深入探讨 freopen,解释其参数并提供实际示例。掌握流重定向可以提高您在各种场景下高效管理输入/输出操作的能力。

什么是 freopen?

C 中的 freopen 函数将现有文件流重新关联到另一个文件。它接受三个参数:文件名、模式和要重定向的流。常见的流包括 stdinstdoutstderr。该函数在成功时返回新的流指针,在失败时返回 NULL。请务必检查返回值以确保重定向成功,并在需要时恢复原始流。

将 stdout 重定向到文件

此示例演示如何使用 freopen 将标准输出重定向到文件。

redirect_stdout.c
#include <stdio.h>

int main() {
    FILE *fp = freopen("output.txt", "w", stdout);
    
    if (fp == NULL) {
        perror("Failed to redirect stdout");
        return 1;
    }

    printf("This text goes to output.txt\n");
    fclose(fp);  // Restores stdout to original destination
    
    return 0;
}

在此,freopenstdout 以写入模式 ("w") 重定向到 "output.txt"。后续的 printf 调用将写入文件而不是控制台。该函数返回新的流指针,我们对此进行错误检查。使用 fclose 关闭文件可将原始 stdout 目标恢复。

将 stdin 从文件重定向

了解如何通过重定向 stdin 从文件读取输入,而不是从键盘读取。

redirect_stdin.c
#include <stdio.h>

int main() {
    FILE *fp = freopen("input.txt", "r", stdin);
    
    if (fp == NULL) {
        perror("Failed to redirect stdin");
        return 1;
    }

    char buffer[100];
    fgets(buffer, sizeof(buffer), stdin);  // Reads from input.txt
    printf("Read from file: %s", buffer);
    
    fclose(fp);  // Restores stdin to original source
    return 0;
}

此代码使用读取模式 ("r") 将 stdin 重定向到从 "input.txt" 读取。然后 fgets 函数从文件读取,而不是等待键盘输入。处理后,fclose 会恢复原始 stdin 源。此技术对于自动化测试很有用。

将 stderr 重定向到文件

通过重定向标准错误流将错误消息捕获到文件中。

redirect_stderr.c
#include <stdio.h>

int main() {
    FILE *fp = freopen("errors.log", "w", stderr);
    
    if (fp == NULL) {
        perror("Failed to redirect stderr");
        return 1;
    }

    fprintf(stderr, "Error: Invalid operation\n");  // Logs to file
    fclose(fp);  // Restores stderr to console
    
    return 0;
}

通过将 stderr 重定向到 "errors.log",所有使用 fprintf(stderr, ...) 写入的错误消息都将转到该文件。这对于记录应用程序错误特别有价值。调用 fclose 可确保后续错误再次出现在控制台上。

临时重定向 stdout

此示例显示了如何临时重定向输出然后恢复它。

temp_redirect.c
#include <stdio.h>

int main() {
    // Save original stdout
    FILE *original_stdout = freopen("temp_output.txt", "w", stdout);
    
    if (original_stdout == NULL) {
        perror("Failed to redirect stdout");
        return 1;
    }

    printf("This goes to temp file\n");
    
    // Restore original stdout
    freopen("/dev/tty", "w", stdout);  // Linux/macOS
    // freopen("CON", "w", stdout);    // Windows
    
    printf("This appears on console\n");
    return 0;
}

代码首先将 stdout 重定向到临时文件。写入一些输出后,它会恢复原始流目标。在类 Unix 系统上,"/dev/tty" 代表终端;Windows 使用 "CON"。当需要临时重定向进行特定操作时,此技术很有用。

组合多个重定向

在一个程序中将 stdoutstderr 重定向到不同的文件。

multi_redirect.c
#include <stdio.h>

int main() {
    FILE *out_file = freopen("output.log", "w", stdout);
    FILE *err_file = freopen("errors.log", "w", stderr);
    
    if (out_file == NULL || err_file == NULL) {
        perror("Redirection failed");
        return 1;
    }

    printf("Regular program output\n");
    fprintf(stderr, "Error message\n");
    
    fclose(out_file);
    fclose(err_file);
    return 0;
}

此示例演示了两个输出流的同时重定向。常规输出转到 "output.log",而错误写入 "errors.log"。每个流都需要自己的 freopen 调用。正确的错误检查可确保在继续程序执行之前两个重定向都成功。

追加到日志文件

在追加模式下使用 freopen 来维护不断增长的日志文件。

append_log.c
#include <stdio.h>

int main() {
    FILE *log_file = freopen("app.log", "a", stdout);
    
    if (log_file == NULL) {
        perror("Failed to open log file");
        return 1;
    }

    printf("Log entry 1\n");
    printf("Log entry 2\n");
    
    fclose(log_file);
    return 0;
}

追加模式 ("a") 可确保新内容被添加到 "app.log" 的末尾,而不会覆盖现有条目。这非常适合您想要保留程序输出历史记录的日志场景。每次运行程序都会向日志中添加内容,而不是从头开始。

重定向到 /dev/null

通过重定向到空设备完全静默输出。

null_redirect.c
#include <stdio.h>

int main() {
    FILE *null_out = freopen("/dev/null", "w", stdout);
    
    if (null_out == NULL) {
        perror("Failed to redirect to /dev/null");
        return 1;
    }

    printf("This won't appear anywhere\n");
    
    // Restore stdout for demonstration
    freopen("/dev/tty", "w", stdout);
    printf("This appears on console\n");
    
    return 0;
}

重定向到 "/dev/null" (在 Windows 上为 "NUL") 将丢弃所有输出。当您想完全抑制输出时,这很有用。该示例演示了之后如何恢复正常输出。请注意,重定向到此处的错误消息也将被静默。

使用 freopen 的最佳实践

来源

C freopen 文档

本教程展示了 freopen 在 C 中进行流重定向的多功能性。从日志记录到输入/输出管理,这些技术都增强了您的文件处理能力。掌握流重定向为灵活的程序设计开辟了新的可能性。

作者

我的名字是 Jan Bodnar,我是一名敬业的程序员,对编码充满热情。自 2007 年以来,我通过 1,400 多篇文章和 8 本电子书分享了我的专业知识。凭借十多年的教学经验,我致力于让编程变得易于访问和引人入胜。

列表 C 标准库