如何根据从二进制文件读取的数据动态分配结构字段?

我有一个看起来像这样的结构:

typedef struct Student {    //dynamically allocated structure
    char *first_name;
    char *last_name;
    float grade;
}Student;

我想要做的是从二进制文件中读取数据并为first_namelast_name字段动态分配内存从普通的.txt文件读取时,我成功完成了这项任务这是代码:

void Read_From_File(const char *file_name, Student *p_destination, const int number_of_students)
{
    FILE *p_file = fopen(file_name, "r");
    if (!p_file)
    {
        perror("Error opening the file. \n");
        exit(EXIT_FAILURE);
    }
    int index = 0;
    while (index < number_of_students)
    {
        unsigned char buffer[256];
        fscanf (p_file, "%s", buffer);
        p_destination[index].last_name = (char*)malloc(strlen(buffer) + 1);
        strcpy(p_destination[index].last_name, buffer);

        fscanf(p_file, "%s", buffer);
        p_destination[index].first_name = (char*)malloc(strlen(buffer) + 1);
        strcpy(p_destination[index].first_name, buffer);

        fscanf(p_file, "%f", &p_destination[index].grade);
        index++;
    }
    fclose(p_file);
}

这很简单,因为fscanf可以单独读取数据并具有类型说明符,如下所示:%s 姓氏/ %s 名字/ %f 等级我不知道如何使用fread读取单个数据,就像我使用fscanf 一样这是我到目前为止尝试过的,但它不起作用:

int number_of_students = 0;
unsigned char buffer[256];
char file_name[10];
FILE *p_file = NULL;
Student *p_students = NULL;

printf("Enter file name. \n");
scanf("%s", file_name);

p_file = fopen(file_name, "rb");

fread(&number_of_students, sizeof(number_of_students), 1, p_file);
p_students = (Student *)malloc(number_of_students * sizeof(Student));
if (!p_students)
{
    perror("Could not allocate memory. \n");
    exit(EXIT_FAILURE);
}

for (int index = 0; index < number_of_students; ++index)
{
    fread(buffer, sizeof(char), 1, p_file);
    p_students[index].last_name = (char *)malloc(strlen(buffer) + 1);
    if (!p_students[index].last_name)
    {
        printf("Could not allocate memory. \n");
        exit(EXIT_FAILURE);
    }
    strcpy(p_students[index].last_name, buffer);

    fread(buffer, sizeof(char), 1, p_file);
    p_students[index].first_name = (char *)malloc(strlen(buffer) + 1);
    if (!p_students[index].first_name)
    {
        printf("Could not allocate memory. \n");
        exit(EXIT_FAILURE);
    }
    strcpy(p_students[index].first_name, buffer);

    fread(&p_students[index].grade, sizeof(float), 1, p_file);
}
Print_Students(p_students, number_of_students);

此外,Print_Students函数如下所示:

void Print_Students(Student *p_students, int number_of_students)
{
    printf("================================================================================================\n");
    for (unsigned int index = 0; index < number_of_students; ++index)
    {
        printf("\t\t===================== Student %d =====================\n\n", index);
        printf("Last name: %s\n", p_students[index].last_name);
        printf("First name: %s\n", p_students[index].first_name);
        printf("Grade: %.2f\n", p_students[index].grade);
    }
    printf("\n");
}

input.txt 文件如下所示:

19
Terresa Minaya 9.50
Otto Pleiman 7 
Illa Holzman 5.25
Alona Greeson 3.40
Natalya Vickrey 10
Catrina Cho 9.34
Loida Dinapoli 9.43
Neely Mcelligott 8.30
Salome Urban 8.75
Rosetta Dagenhart 9.10
Diane Cooksey 10
Novella Longmire 3
Gilberte Manganaro 4
Joye Humbert 5
Justa Larock 6
Delana Bufkin 7
Genaro Kenison 8.98
Refugio Arena 4.56
Iona Nida 7.65

我将这个文件中的数据加载到我的学生向量中,然后我根据我的向量中的数据编写了input.bin文件。我使用以下代码写入二进制文件:

void Write_To_Binary(const char *file_name, Student *p_source, const int number_of_students)
{   
    size_t successfully_written = 0;
    FILE *p_file = fopen(file_name, "wb");
    if (!p_file)
    {
        perror("Error opening the file. \n");
        exit(EXIT_FAILURE);
    }
    successfully_written = fwrite(&number_of_students, sizeof(number_of_students), 1, p_file);
    if (successfully_written != 1)
    {
        perror("Error writing to the file. \n");
        exit(EXIT_FAILURE);
    }
    successfully_written = fwrite(p_source, sizeof(Student), number_of_students, p_file);
    if (successfully_written != number_of_students)
    {
        perror("Error writing all the student data. \n");
        exit(EXIT_FAILURE);
    }
    fclose(p_file);
}

更新:我遵循了 iBug 的解决方案并且它有效。我更改了数据字段,如下所示: sizeof(last_name) last_name sizeof(first_name) first_name Grade。

我将在这里发布我用来写入 bin 文件并从中读取的函数。

这是函数Write_To_Binary

    void Write_To_Binary(const char *file_name, Student *p_source, const unsigned int number_of_students)
{
    FILE *p_file = fopen(file_name, "wb");
    if (!p_file)
    {
        perror("Error opening the file. \n");
        exit(EXIT_FAILURE);
    }

    size_t successfully_written = 0;
    successfully_written = fwrite(&number_of_students, sizeof(number_of_students), 1, p_file);
    if (successfully_written != 1)
    {
        printf("Error writing to the file. \n");
        exit(EXIT_FAILURE);
    }

    unsigned int width = 0, width1 = 0;
    for (unsigned int index = 0; index < number_of_students; ++index)
    {
        width = strlen(p_source[index].last_name) + 1;

        successfully_written = fwrite(&width, sizeof(width), 1, p_file);
        printf("Name: %s Width: %d \n", p_source[index].last_name, width);
        if (successfully_written != 1)
        {
            printf("Error writing to the file. \n");
            exit(EXIT_FAILURE);
        }

        successfully_written = fwrite(p_source[index].last_name, width, 1, p_file);
        if (successfully_written != 1)
        {
            printf("Error writing to the file. \n");
            exit(EXIT_FAILURE);
        }

        width = strlen(p_source[index].first_name) + 1;

        successfully_written = fwrite(&width, sizeof(width), 1, p_file);
        if (successfully_written != 1)
        {
            printf("Error writing to the file. \n");
            exit(EXIT_FAILURE);
        }

        successfully_written = fwrite(p_source[index].first_name, width, 1, p_file);
        if (successfully_written != 1)
        {
            printf("Error writing to the file. \n");
            exit(EXIT_FAILURE);
        }

        successfully_written = fwrite(&p_source[index].grade, sizeof(float), 1, p_file);
        if (successfully_written != 1)
        {
            printf("Error writing to the file. \n");
            exit(EXIT_FAILURE);
        }
    }

    fclose(p_file);
}

这是函数Read_From_Binary

void Read_From_Binary(const char *file_name, Student *p_destination)
{
    FILE *p_file = fopen(file_name, "rb");
    if (!p_file)
    {
        perror("Error opening file. \n");
        exit(EXIT_FAILURE);
    }

    unsigned int number_of_students = 0;
    size_t successfully_read;
    successfully_read = fread(&number_of_students, sizeof(number_of_students), 1, p_file);
    if (successfully_read != 1)
    {
        printf("Error reading the number of students. \n");
        exit(EXIT_FAILURE);
    }

    unsigned int width = 0;
    for (unsigned int index = 0; index < number_of_students; ++index)
    {
        successfully_read = fread(&width, sizeof(width), 1, p_file);
        if (successfully_read != 1)
        {
            printf("Error reading from the file. \n");
            exit(EXIT_FAILURE);
        }

        p_destination[index].last_name = (char*)malloc(width);
        if (!p_destination[index].last_name)
        {
            printf("Could not allocate memory. \n");
            exit(EXIT_FAILURE);
        }
        successfully_read = fread(p_destination[index].last_name, width, 1, p_file);
        if (successfully_read != 1)
        {
            printf("Error reading from the file. \n");
            exit(EXIT_FAILURE);
        }

        successfully_read = fread(&width, sizeof(width), 1, p_file);
        if (successfully_read != 1)
        {
            printf("Error reading from the file. \n");
            exit(EXIT_FAILURE);
        }

        p_destination[index].first_name = (char*)malloc(width);
        if (!p_destination[index].first_name)
        {
            printf("Could not allocate memory. \n");
            exit(EXIT_FAILURE);
        }
        successfully_read = fread(p_destination[index].first_name, width, 1, p_file);
        if (successfully_read != 1)
        {
            printf("Error reading from the file. \n");
            exit(EXIT_FAILURE);
        }

        successfully_read = fread(&p_destination[index].grade, sizeof(float), 1, p_file);
        if (successfully_read != 1)
        {
            printf("Error reading from the file. \n");
            exit(EXIT_FAILURE);
        }
    }

    fclose(p_file);
}
臭虫

在最近的一个项目中了类似的工作

我自己实现了一个二进制文件格式,它的结构是

MAGIC
number of records
record 1
    (int) length of this record
    data
record 2
    (int) length of this record
    data

所以你可以多留一个 4 个字节(或一个整数)来表示要读取的内容的长度,并根据该数字进行读取。

这种实现的优点是:

  • 您不需要先读取另一个缓冲区,这可能会增加对记录长度的额外限制。
  • 当内容格式发生变化时,您不必担心阅读长度。
  • 不需要使用单个字符作为“终止符”,因为长度是预先确定的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从二进制文件读取多个结构

来自分类Dev

如何从二进制文件读取多个结构

来自分类Dev

如何从dicom文件读取二进制数据?

来自分类Dev

如何读取具有给定结构的多种数据类型的二进制文件

来自分类Dev

如何读取具有给定结构的多种数据类型的二进制文件

来自分类Dev

读取结构化二进制文件c ++

来自分类Dev

无法从二进制文件中读取结构

来自分类Dev

从具有给定数据结构的二进制文件中读取

来自分类Dev

动态分配数组上的二进制搜索

来自分类Dev

静态链接的二进制文件如何小于动态链接的二进制文件?

来自分类Dev

如何在C中将二进制文件读取到结构

来自分类Dev

如何从Rust中的二进制文件读取C结构?

来自分类Dev

逐条记录从二进制文件读取数据

来自分类Dev

PHP从二进制文件读取数据

来自分类Dev

PHP从二进制文件读取数据

来自分类Dev

从.dat二进制文件读取数据

来自分类Dev

从文件中读取双二进制数据

来自分类Dev

二进制文件写入顺序如何结构?

来自分类Dev

如何更新二进制文件中的结构项

来自分类Dev

如何在pyspark中读取二进制数据

来自分类Dev

如何使用VBScript从二进制文件读取

来自分类Dev

如何优化C ++二进制文件读取?

来自分类Dev

如何在Julia中读取二进制文件?

来自分类Dev

读取时如何移入二进制文件?

来自分类Dev

如何使用VBScript从二进制文件读取

来自分类Dev

如何逐字节读取二进制文件?

来自分类Dev

如何使用 WINAPI 读取整个二进制文件?

来自分类Dev

二进制数据的Python结构

来自分类Dev

Word文件的二进制结构