C语言数组如何存文件?

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 C语言 正文

使用 fprintffscanf (文本格式)

这是最直观的方法,将数组元素以人类可读的文本形式(用空格或换行符分隔)写入文件。

优点:

  • 可读,可以用记事本等工具直接打开查看。
  • 调试方便。

缺点:

  • 占用空间可能比二进制格式大。
  • 读写速度相对较慢,因为涉及到文本格式转换。
  • 如果数组元素本身包含空格或特殊字符,可能会被错误解析。

保存数组到文件 (fprintf)

#include <stdio.h>
int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    // 1. 打开文件 (w: 写模式,如果文件存在则覆盖)
    FILE *file = fopen("array_data.txt", "w");
    if (file == NULL) {
        perror("无法打开文件进行写入");
        return 1;
    }
    // 2. 将数组大小写入文件,方便后续读取
    fprintf(file, "%d\n", size);
    // 3. 循环写入数组元素
    for (int i = 0; i < size; i++) {
        fprintf(file, "%d ", numbers[i]); // 用空格分隔
        // 或者用换行符 fprintf(file, "%d\n", numbers[i]);
    }
    // 4. 关闭文件
    fclose(file);
    printf("数组已成功保存到 array_data.txt\n");
    return 0;
}

从文件读取数组 (fscanf)

读取时,需要先读取数组的大小,然后循环读取相应数量的元素。

#include <stdio.h>
int main() {
    int size;
    int read_numbers[100]; // 假设数组最大为100
    // 1. 打开文件 (r: 读模式)
    FILE *file = fopen("array_data.txt", "r");
    if (file == NULL) {
        perror("无法打开文件进行读取");
        return 1;
    }
    // 2. 先读取数组大小
    if (fscanf(file, "%d", &size) != 1) {
        printf("读取数组大小失败\n");
        fclose(file);
        return 1;
    }
    // 3. 循环读取数组元素
    for (int i = 0; i < size; i++) {
        if (fscanf(file, "%d", &read_numbers[i]) != 1) {
            printf("读取第 %d 个元素失败\n", i);
            break; // 提前终止循环
        }
    }
    // 4. 关闭文件
    fclose(file);
    // 5. 验证读取结果
    printf("从文件中读取的数组大小为: %d\n", size);
    printf("数组内容为: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", read_numbers[i]);
    }
    printf("\n");
    return 0;
}

使用 fwritefread (二进制格式)

这种方法直接将数组在内存中的二进制数据块原封不动地写入文件,这是最高效、最节省空间的方法。

优点:

  • 读写速度极快。
  • 文件体积小,没有格式开销。
  • 可以处理任何类型的数据(结构体、浮点数等),只要保证写入和读取时的数据类型一致。

缺点:

  • 是二进制码,无法直接用文本编辑器阅读,可读性差。

保存数组到文件 (fwrite)

#include <stdio.h>
int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    // 1. 打开文件 (wb: 二进制写模式)
    FILE *file = fopen("array_data.bin", "wb");
    if (file == NULL) {
        perror("无法打开文件进行二进制写入");
        return 1;
    }
    // 2. 将整个数组一次性写入文件
    // fwrite(数组地址, 每个元素的大小, 元素个数, 文件指针)
    size_t elements_written = fwrite(numbers, sizeof(int), size, file);
    if (elements_written != size) {
        printf("写入元素数量不匹配!\n");
    }
    // 3. 关闭文件
    fclose(file);
    printf("数组已成功以二进制格式保存到 array_data.bin\n");
    return 0;
}

从文件读取数组 (fread)

读取时,同样是一次性读取整个数据块到内存中。

#include <stdio.h>
int main() {
    int read_numbers[100]; // 必须有足够大的空间来存放读取的数据
    int size;
    // 1. 打开文件 (rb: 二进制读模式)
    FILE *file = fopen("array_data.bin", "rb");
    if (file == NULL) {
        perror("无法打开文件进行二进制读取");
        return 1;
    }
    // 2. 一次性读取整个数组
    // fread(存放地址, 每个元素的大小, 元素个数, 文件指针)
    size_t elements_read = fread(read_numbers, sizeof(int), 5, file); // 我们知道原数组有5个元素
    // 获取实际读取的元素个数
    size = elements_read;
    // 3. 关闭文件
    fclose(file);
    // 4. 验证读取结果
    printf("从二进制文件中读取的数组大小为: %zu\n", elements_read);
    printf("数组内容为: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", read_numbers[i]);
    }
    printf("\n");
    return 0;
}

注意: 使用 fread 时,你需要预先知道要读取多少个元素(你可以在文件开头单独写入一个 size 变量)。


混合方法(推荐)

这是最健壮的方法,结合了两种方式的优点:先写入数组的大小,再以二进制格式写入整个数组

这样,读取文件时,第一步就能知道要读取多少个数据,避免了缓冲区溢出或读取不完整的问题。

保存(写入大小 + 二进制数据)

#include <stdio.h>
int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    FILE *file = fopen("array_data_mixed.bin", "wb");
    if (file == NULL) {
        perror("无法打开文件");
        return 1;
    }
    // 1. 先写入数组大小
    fwrite(&size, sizeof(int), 1, file);
    // 2. 再写入数组数据
    fwrite(numbers, sizeof(int), size, file);
    fclose(file);
    printf("数组已成功以混合格式保存到 array_data_mixed.bin\n");
    return 0;
}

读取(先读大小,再读数据)

#include <stdio.h>
int main() {
    int read_numbers[100];
    int size;
    FILE *file = fopen("array_data_mixed.bin", "rb");
    if (file == NULL) {
        perror("无法打开文件");
        return 1;
    }
    // 1. 先读取数组大小
    if (fread(&size, sizeof(int), 1, file) != 1) {
        printf("读取数组大小失败\n");
        fclose(file);
        return 1;
    }
    // 2. 检查大小是否在安全范围内
    if (size > 100) {
        printf("错误:文件中的数组大小超过了缓冲区容量!\n");
        fclose(file);
        return 1;
    }
    // 3. 读取数组数据
    size_t elements_read = fread(read_numbers, sizeof(int), size, file);
    if (elements_read != size) {
        printf("警告:读取的元素数量与文件头声明的不一致,\n");
    }
    fclose(file);
    // 4. 验证
    printf("从混合文件中读取的数组大小为: %d\n", size);
    printf("数组内容为: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", read_numbers[i]);
    }
    printf("\n");
    return 0;
}

总结与对比

特性 fprintf / fscanf (文本) fwrite / fread (二进制) 混合方法 (推荐)
可读性 ,可手动编辑 ,二进制乱码 ,文件头可读
文件大小 较大 较小
读写速度 较慢
数据安全性 一般,易受格式影响 ,原样读写 ,有长度校验
适用场景 配置文件、需要人工查看的数据 大数据量、性能敏感的场景(如游戏存档、科学计算) 绝大多数情况下的最佳选择,兼顾了安全性和效率

核心建议:

  • 如果数据需要被人类阅读或编辑,使用方法一
  • 如果追求极致的性能和最小的文件体积,并且不关心文件的可读性,使用方法二
  • 对于绝大多数程序内部的数据持久化需求,方法三(混合方法)是最安全、最可靠的选择。
-- 展开阅读全文 --
头像
c语言func什么意思
« 上一篇 今天
dede文件夹有哪些核心功能及作用?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]