ZetCode

C fwrite 函数

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

在 C 编程中,二进制文件处理对于高效的数据存储至关重要。fwrite 函数可以精确地将二进制数据写入文件。本教程将解释 fwrite 的参数,演示各种用例,并提供实际示例。掌握 fwrite 可让您处理复杂的数据结构并优化存储。

什么是 fwrite?

fwrite 函数在 C 中将二进制数据写入文件。它接受四个参数:指向数据的指针、每个元素的大小、元素的数量和文件指针。fwrite 返回成功写入的元素数量。在处理 fwrite 时,请务必使用二进制模式(“wb”、“ab”或“rb+”)以防止数据损坏。

写入单个整数

此示例演示了如何将单个整数写入二进制文件。

write_int.c
#include <stdio.h>

int main() {
    FILE *fp;
    int num = 42;

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

    size_t written = fwrite(&num, sizeof(int), 1, fp);
    if (written != 1) {
        printf("Error writing to file\n");
    }

    fclose(fp);
    return 0;
}

在此,我们在二进制写入模式(“wb”)下打开“data.bin”。fwrite 函数将内存中的一个整数(通常为 4 字节)写入文件。我们检查返回值以确保写入成功。完成后务必使用 fclose 关闭文件。

写入整数数组

了解如何使用 fwrite 一次写入多个整数。

write_array.c
#include <stdio.h>

int main() {
    FILE *fp;
    int nums[] = {10, 20, 30, 40, 50};
    size_t count = sizeof(nums)/sizeof(nums[0]);

    fp = fopen("array.bin", "wb");
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    size_t written = fwrite(nums, sizeof(int), count, fp);
    if (written != count) {
        printf("Incomplete write operation\n");
    }

    fclose(fp);
    return 0;
}

此示例一次性写入整个整数数组。我们使用 sizeof 算术来计算元素数量。fwrite 高效地处理整个数组,一次性写入所有元素。成功写入的返回值应与我们的元素计数相匹配。

写入结构体

了解如何将自定义数据结构写入二进制文件。

write_struct.c
#include <stdio.h>

typedef struct {
    int id;
    char name[20];
    float score;
} Student;

int main() {
    FILE *fp;
    Student s = {1, "Alice", 95.5};

    fp = fopen("student.bin", "wb");
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    size_t written = fwrite(&s, sizeof(Student), 1, fp);
    if (written != 1) {
        printf("Failed to write structure\n");
    }

    fclose(fp);
    return 0;
}

在这里,我们定义了一个 Student 结构体,并将一个实例写入文件。fwrite 以二进制格式写入整个结构体,包括所有字段。这种方法保留了结构体的精确内存布局。请注意,由于填充,直接写入结构体是平台相关的。

写入多个结构体

使用此技术高效存储结构体集合。

write_struct_array.c
#include <stdio.h>

typedef struct {
    int x;
    int y;
} Point;

int main() {
    FILE *fp;
    Point points[] = {{1,2}, {3,4}, {5,6}};
    size_t count = sizeof(points)/sizeof(points[0]);

    fp = fopen("points.bin", "wb");
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    size_t written = fwrite(points, sizeof(Point), count, fp);
    if (written != count) {
        printf("Partial structure array written\n");
    }

    fclose(fp);
    return 0;
}

此示例将一个 Point 结构体数组写入二进制文件。我们动态计算元素数量。fwrite 一次性处理整个数组,对于大型数据集来说非常高效。二进制文件将包含结构体的确切内存表示。

追加二进制数据

将数据添加到现有的二进制文件中,而不会覆盖之前的内容。

append_binary.c
#include <stdio.h>

int main() {
    FILE *fp;
    float new_data[] = {1.1, 2.2, 3.3};

    fp = fopen("data.bin", "ab");  // Append binary mode
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }

    size_t written = fwrite(new_data, sizeof(float), 3, fp);
    if (written != 3) {
        printf("Failed to append all data\n");
    }

    fclose(fp);
    return 0;
}

使用二进制追加模式(“ab”),新数据将被添加到现有文件内容的末尾。文件指针会自动从末尾开始。此示例追加了三个浮点值。当您想保留文件中的现有数据时,追加模式比写入模式更安全。

写入和读回

演示了二进制数据的完整写入-读取周期。

write_read.c
#include <stdio.h>

int main() {
    FILE *fp;
    double data[] = {3.14, 2.718, 1.618};
    double read_data[3];

    // Write data
    fp = fopen("numbers.bin", "wb");
    if (fp == NULL) {
        perror("Failed to open file for writing");
        return 1;
    }
    fwrite(data, sizeof(double), 3, fp);
    fclose(fp);

    // Read data
    fp = fopen("numbers.bin", "rb");
    if (fp == NULL) {
        perror("Failed to open file for reading");
        return 1;
    }
    fread(read_data, sizeof(double), 3, fp);
    fclose(fp);

    // Verify
    for (int i = 0; i < 3; i++) {
        printf("%f ", read_data[i]);
    }
    printf("\n");

    return 0;
}

这个完整的示例将一个双精度数组写入文件,然后将它们读回。我们使用二进制写入模式(“wb”)进行写入,使用二进制读取模式(“rb”)进行读取。打印值以验证它们是否已正确存储和检索。这种模式在二进制数据持久化中很常见。

写入动态数据

使用 fwrite 处理动态分配的内存。

write_dynamic.c
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fp;
    int *dynamic_array;
    size_t count = 5;

    // Allocate and initialize array
    dynamic_array = malloc(count * sizeof(int));
    if (dynamic_array == NULL) {
        perror("Memory allocation failed");
        return 1;
    }

    for (size_t i = 0; i < count; i++) {
        dynamic_array[i] = i * 10;
    }

    // Write to file
    fp = fopen("dynamic.bin", "wb");
    if (fp == NULL) {
        perror("Failed to open file");
        free(dynamic_array);
        return 1;
    }

    size_t written = fwrite(dynamic_array, sizeof(int), count, fp);
    if (written != count) {
        printf("Partial write occurred\n");
    }

    fclose(fp);
    free(dynamic_array);
    return 0;
}

此示例演示了如何将动态分配的内存写入文件。我们分配一个整数数组,初始化它,然后将其写入磁盘。相同的 fwrite 方法可用于堆栈和堆内存。完成后请记住释放分配的内存并关闭文件。

使用 fwrite 的最佳实践

来源

C fwrite 文档

本教程深入探讨了 fwrite 函数,从基本的整数写入到复杂的结构体处理。二进制文件操作是 C 程序中实现高效数据存储和检索的强大工具。

作者

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

列表 C 标准库