• C- fread() & fwrite()


    fread()

    fread() 是 C 语言中的标准库函数,用于从文件或流中读取数据。它是一个非常强大且通用的函数,经常用于读取二进制文件,但也可以用于读取文本文件。

    函数原型:

    size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
    
    • 1

    参数:

    1. ptr: 一个指向内存的指针,该内存将存储从文件中读取的数据。通常,这是一个指向大型缓冲区或结构的指针。
    2. size: 要读取的每个数据项的大小(以字节为单位)。
    3. count: 要读取的数据项数量。
    4. stream: 一个指向 FILE 的指针,表示要从中读取数据的文件或流。

    返回值:

    • 返回实际读取的数据项数。如果出现错误或到达文件末尾,该数字可能小于 count。特别地,如果遇到文件末尾或错误,fread() 可能返回一个小于 count 的值。

    错误:

    • 如果发生错误,可以使用 ferror() 函数来检查。
    • 使用 feof() 可以检查是否已到达文件的末尾。

    示例:

    以下是一个示例,展示如何使用 fread() 从一个二进制文件中读取整数:

    #include 
    
    int main() {
        FILE *file;
        int buffer[10]; // 数组,用于存储从文件中读取的整数
        size_t n;
    
        file = fopen("data.bin", "rb");
        if (file == NULL) {
            perror("Failed to open file");
            return 1;
        }
    
        n = fread(buffer, sizeof(int), 10, file); // 尝试读取10个整数
    
        for (size_t i = 0; i < n; i++) {
            printf("Read integer: %d\n", buffer[i]);
        }
    
        fclose(file);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在上面的示例中,我们打开了一个名为 data.bin 的二进制文件,并尝试从中读取 10 个整数。然后,我们打印出实际读取的整数。

    注意:当使用 fread()fwrite() 等函数进行文件 I/O 操作时,通常推荐以二进制模式(如 “rb” 或 “wb”)打开文件,尤其是在跨平台的代码中,以避免任何潜在的换行符转换问题。

    fwrite()

    fwrite() 是 C 语言标准库中的一个函数,用于将数据写入文件或流。它通常用于写入二进制文件,但也可以用于写入文本文件。与 fread() 相似,它是用于文件I/O的底层函数,可以用来写入各种类型的数据。

    函数原型:

    size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
    
    • 1

    参数:

    1. ptr: 一个指向要写入文件的数据的指针。
    2. size: 每个数据项的大小(以字节为单位)。
    3. count: 要写入的数据项数量。
    4. stream: 一个指向 FILE 的指针,表示要将数据写入的文件或流。

    返回值:

    • 返回实际写入的数据项数。如果这个数字小于 count,则表示可能发生了错误。

    示例:

    以下是一个示例,展示如何使用 fwrite() 将整数数组写入一个二进制文件:

    #include 
    
    int main() {
        FILE *file;
        int data[5] = {1, 2, 3, 4, 5};
    
        file = fopen("data.bin", "wb");
        if (file == NULL) {
            perror("Failed to open file");
            return 1;
        }
    
        size_t n = fwrite(data, sizeof(int), 5, file);
        if (n != 5) {
            printf("Error writing to file.\n");
            fclose(file);
            return 2;
        }
    
        printf("Successfully wrote %zu items to the file.\n", n);
        
        fclose(file);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在上述示例中,我们打开了一个名为 data.bin 的二进制文件(或创建了该文件,如果它不存在的话),然后尝试向其中写入一个整数数组。完成写入后,我们输出写入的数据项数。

    注意:与 fread() 一样,当使用 fwrite() 进行文件 I/O 操作时,推荐以二进制模式(例如 “wb”)打开文件,特别是在跨平台代码中,以避免潜在的换行符转换问题。

    综合案例

    1、二进制文件读写

    让我们考虑一个场景,其中有一个包含学生信息的结构体,并且我们希望将这些学生信息保存到一个二进制文件中,然后再从该文件中读取这些信息。

    #include 
    #include 
    
    #define FILENAME "students.bin"
    #define MAX_NAME 100
    
    typedef struct {
        char name[MAX_NAME];
        int age;
        float gpa;
    } Student;
    
    void saveStudentToFile(const Student *student) {
        FILE *file = fopen(FILENAME, "wb");
        if (!file) {
            perror("Failed to open file for writing");
            return;
        }
    
        if (fwrite(student, sizeof(Student), 1, file) != 1) {
            printf("Error writing to file.\n");
        }
    
        fclose(file);
    }
    
    void readStudentFromFile(Student *student) {
        FILE *file = fopen(FILENAME, "rb");
        if (!file) {
            perror("Failed to open file for reading");
            return;
        }
    
        if (fread(student, sizeof(Student), 1, file) != 1) {
            printf("Error reading from file.\n");
        }
    
        fclose(file);
    }
    
    int main() {
        Student s1 = {"Alice", 20, 3.5};
        saveStudentToFile(&s1);
    
        Student s2;
        readStudentFromFile(&s2);
    
        printf("Name: %s\nAge: %d\nGPA: %.2f\n", s2.name, s2.age, s2.gpa);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在上述程序中:

    1. 我们定义了一个名为 Student 的结构体,用于存储学生的 nameagegpa
    2. saveStudentToFile 函数接收一个 Student 结构体的指针,并将其内容写入一个名为 “students.bin” 的二进制文件。
    3. readStudentFromFile 函数读取 “students.bin” 文件的内容并将其填充到提供的 Student 结构体中。
    4. main 函数中,我们创建了一个名为 s1Student 结构体实例,并保存它。然后我们创建了一个名为 s2 的空的 Student 结构体,并从文件中填充其内容。最后,我们打印出从文件中读取的学生信息。

    程序运行结果如下:

    Name: Alice
    Age: 20
    GPA: 3.50
    
    • 1
    • 2
    • 3

    这个示例展示了如何使用 fread()fwrite() 进行基本的文件 I/O,特别是用于保存和读取结构体数据。

    2、文本文件读写

    当然,文本文件的读写与二进制文件有所不同。文本文件通常使用诸如 fprintf()fscanf()fgets()fputs() 之类的函数。这些函数为我们提供了更高级的文本处理能力。

    下面的示例演示了如何将学生的信息写入文本文件,并从文本文件中读取它:

    #include 
    #include 
    
    #define FILENAME "students.txt"
    #define MAX_NAME 100
    
    typedef struct {
        char name[MAX_NAME];
        int age;
        float gpa;
    } Student;
    
    void saveStudentToFile(const Student *student) {
        FILE *file = fopen(FILENAME, "w");
        if (!file) {
            perror("Failed to open file for writing");
            return;
        }
    
        fprintf(file, "%s\n%d\n%f\n", student->name, student->age, student->gpa);
    
        fclose(file);
    }
    
    void readStudentFromFile(Student *student) {
        FILE *file = fopen(FILENAME, "r");
        if (!file) {
            perror("Failed to open file for reading");
            return;
        }
    
        fscanf(file, "%99s\n%d\n%f\n", student->name, &student->age, &student->gpa);
    
        fclose(file);
    }
    
    int main() {
        Student s1 = {"Alice", 20, 3.5};
        saveStudentToFile(&s1);
    
        Student s2;
        readStudentFromFile(&s2);
    
        printf("Name: %s\nAge: %d\nGPA: %.2f\n", s2.name, s2.age, s2.gpa);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    在上述程序中:

    1. 我们仍然使用了 Student 结构体来保存学生信息。
    2. saveStudentToFile 函数使用 fprintf() 将学生信息格式化为字符串并写入文件。
    3. readStudentFromFile 函数使用 fscanf() 从文件中读取格式化的文本,并填充到提供的 Student 结构体中。
    4. main 函数中,我们的操作与之前的示例相似,但这次我们是读写一个文本文件而不是二进制文件。

    程序运行结果如下:

    Name: Alice
    Age: 20
    GPA: 3.50
    
    • 1
    • 2
    • 3

    注意:当处理文本文件时,需要注意文件中的换行符和空格,因为它们可能会影响到 fscanf() 的行为。在实践中,对于真实的应用程序,可能需要使用更健壮的解析方法,例如结合 fgets()sscanf() 来读取和解析文本行。

  • 相关阅读:
    基于Spring Boot的房屋租赁系统
    es字段查询加keyword和不加keyword的区别
    牛客网基础知识强化巩固-周结04
    论文阅读 (65):RePaint: Inpainting using Denoising Diffusion Probabilistic Models
    cache2go-源码阅读
    .Net开源迁移框架FluentMigrator的使用。
    LeetCode简单题之两个数组间的距离值
    Rabbitmq元数据导入导出
    PyCharm新手入门
    1526_AURIX TC275 BootROM下
  • 原文地址:https://blog.csdn.net/weixin_43844521/article/details/134024255