ZetCode

C fopen 函数

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

文件处理是 C 编程中的一项基本技能,使您能够有效地读取和写入文件。fopen 函数是您进行文件操作的门户,提供各种模式以满足您的需求。本教程将深入介绍 fopen 的基础知识,解释其模式,并提供实际示例以巩固您的理解。掌握文件处理可确保程序中可靠的数据管理和流畅的 I/O 操作。

什么是 fopen?

C 中的 fopen 函数用于打开文件并返回一个 FILE 指针以供后续操作。它需要两个参数:文件的名称(或路径)以及模式,该模式定义了您打算如何与文件进行交互。常见模式包括读取、写入或追加。始终验证 fopen 是否不返回 NULL 以及早捕获错误,并在完成后使用 fclose 正确关闭文件。

以读取模式打开文件

让我们探讨如何以读取模式使用 fopen 打开和读取文本文件。

read_file.c
#include <stdio.h>

int main() {
    FILE *fp;
    char ch;

    fp = fopen("data.txt", "r");  // Open file in read-only mode

    if (fp == NULL) {
        perror("Failed to open file");  // Improved error reporting
        return 1;
    }

    while ((ch = fgetc(fp)) != EOF) {  // Read and display each character
        putchar(ch);
    }

    fclose(fp);  // Release file resources
    return 0;
}

在这里,fopen 以读取模式(“r”)打开“data.txt”。如果文件不存在或无法访问,fp 将为 NULL,我们使用 perror 提供详细的错误反馈。fgetc 函数逐个字符读取,直到遇到文件结束标记 (EOF)。最后,fclose 确保文件被正确关闭。

以写入模式打开文件

接下来,看看如何使用 fopen 的写入模式创建或覆盖文件。

write_file.c
#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("notes.txt", "w");  // Open file in write mode

    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    fprintf(fp, "Welcome to C file handling!\n");  // Write a greeting
    fclose(fp);  // Close the file to save changes

    return 0;
}

在此示例中,fopen 以写入模式(“w”)打开“notes.txt”,如果文件不存在则创建它,如果存在则覆盖它。fprintf 函数将格式化字符串写入文件。使用 fclose 关闭文件可确保数据已保存并释放了资源。

追加到文件

了解如何使用追加模式将内容添加到现有文件的末尾。

append_file.c
#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("notes.txt", "a");  // Open file in append mode

    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    fprintf(fp, "Adding a new note.\n");  // Append text
    fclose(fp);  // Save and close

    return 0;
}

使用追加模式(“a”),fopen 将文件指针定位在“notes.txt”的末尾。通过 fprintf 写入的新数据将被添加,而不会覆盖现有内容。如果文件不存在,它将被创建。关闭文件可确保追加的数据已存储。

读写二进制数据

使用 fopen 的二进制模式处理非文本数据,例如整数。

binary_file.c
#include <stdio.h>

int main() {
    FILE *fp;
    int numbers[] = {10, 20, 30, 40, 50};
    int read_numbers[5];

    // Write binary data
    fp = fopen("numbers.bin", "wb");  // Binary write mode
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    fwrite(numbers, sizeof(int), 5, fp);  // Write array
    fclose(fp);

    // Read binary data
    fp = fopen("numbers.bin", "rb");  // Binary read mode
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }
    fread(read_numbers, sizeof(int), 5, fp);  // Read into array
    fclose(fp);

    // Display results
    printf("Read values: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", read_numbers[i]);
    }
    printf("\n");

    return 0;
}

二进制写入模式(“wb”)和读取模式(“rb”)允许 fopen 管理原始数据。fwrite 函数存储一个整数数组,而 fread 则检索它。二进制模式会精确保留数据,因此非常适合图像或数据集等非文本文件。

逐行读取文件

使用此示例逐行读取文本文件,以便于处理。

read_lines.c
#include <stdio.h>

int main() {
    FILE *fp;
    char line[128];  // Increased buffer for safety

    fp = fopen("data.txt", "r");
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    while (fgets(line, sizeof(line), fp) != NULL) {  // Read each line
        printf("Line: %s", line);
    }

    fclose(fp);
    return 0;
}

fgets 函数读取最多一个换行符或 EOF,并将结果存储在缓冲区中。在这里,一个 128 个字符的缓冲区可以容纳更长的行。循环继续,直到 fgets 返回 NULL,表示文件结束。此方法非常适合解析结构化文本文件。

检查文件是否存在

在此简单检查中,在执行操作之前验证文件是否存在。

file_exists.c
#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("missing.txt", "r");  // Attempt to open in read mode
    if (fp == NULL) {
        printf("File not found.\n");
        return 1;
    }

    printf("File exists!\n");
    fclose(fp);
    return 0;
}

使用 fopen 以读取模式(“r”)打开文件,如果文件不存在则返回 NULL。此技术是测试文件是否存在的一种快捷方法。如果文件成功打开,请勿忘记使用 fclose 关闭它。

更新文件

通过使用更新模式读取和写入来修改现有文件。

update_file.c
#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("data.txt", "r+");  // Open for reading and writing
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    // Read and display first character
    char ch = fgetc(fp);
    printf("Original first character: %c\n", ch);

    // Overwrite first character
    rewind(fp);  // Reset pointer to start
    fputc('Z', fp);  // Replace with 'Z'

    fclose(fp);
    return 0;
}

更新模式(“r+”)允许 fopen 进行读取和写入。文件必须存在,否则将返回 NULL。在这里,我们读取第一个字符,使用 rewind 重置指针,然后覆盖它。在进行较大的更新时,请使用 fseek 进行精确的定位。

使用 fopen 的最佳实践

来源

C fopen 文档

本教程介绍了 C 中 fopen 的强大功能,并展示了从基本读取到二进制操作的实际示例。有效的文件处理是构建可靠、数据驱动型应用程序的关键。

作者

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

列表 C 标准库