【问题标题】:Saving structs to file将结构保存到文件
【发布时间】:2020-11-23 10:21:12
【问题描述】:

我正在尝试将结构列表保存到文件中并稍后加载它们。

我想从对象数组中输出第一个对象的数据,但是当我尝试通过他的指针(变量:nameage)加载和打印结构的对象时,程序的输出是什么像这样:Name: | Age: 0

预期是:Name: Tom | Age: 15

(对于person object[3] = {"Tom", 15, "Andrew", 25, "Kate", 55};的示例输入)。

我尝试为此使用fseek 函数,如何使用它仅打印第一个对象?

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

    typedef struct
    {
        char name[20];
        int age;
    } person;

    void save(int x, char way[100], person (*p_object)[x]);
    void load(char way[100], int x);

    FILE *file;

    int main(void)
    {
        char way[100] = "D:\\Projects\\C\\C06_WorkingWithFiles\\C005_PositioningInTheStream.dat";
        person object[3] = {"Tom", 15, "Andrew", 25, "Kate", 55};
        person (*p_object)[3] = &object;
        save((sizeof(*p_object) / sizeof(*p_object)[0]), way, p_object);
        load(way, 1);
        fclose(file);
        return 0;
    }

    void save(int x, char way[100], person (*p_object)[x])
    {
        if (fopen(way, "r") == NULL)
        {
            file = fopen(way, "w");
        }

        char *c = (char *)p_object;
        for (int i = 0; i < sizeof(*p_object); i++)
        {
            putc(*c, file);
            c++;
        }
    }

    void load(char way[100], int x)
    {
        if ((fopen(way, "r")) == NULL)
        {
            perror("\nError");
            exit(0);
        }

        int position = sizeof(person) * x;
        fseek(file, position, SEEK_SET);

        person object, *p_object = &object;
        char symbol, *c = (char *)p_object;
        while ((symbol = getc(file)) != EOF)
        {
            *c = symbol;
            c++;
        }
        printf("\nName: %s | Age: %d\n", p_object -> name, p_object -> age);
    }

【问题讨论】:

  • 是否将数据保存到文件中?您正在检查文件是否存在,如果是,则您没有实例化“文件”指针。因此,如果文件存在,它将不会保存数据。最好在 save() 和 load() 函数中成对使用 fopen()/fclose,并在每个函数中将 fopen 分配给“文件”指针变量。

标签: c struct file-io


【解决方案1】:

这是一个满足您要求的实现:

#include <stdio.h>

typedef struct {
    char name[20];
    int age;
} person;

void save(int num, char path[100], person (*p_object)[num]);

person load(char path[100], int index);


int main(void) {
    char path[100] = "output.dat";
    person persons[3] = {"Tom", 15, "Andrew", 25, "Kate", 55};

    save(3, path, &persons);
    person object = load(path, 1);
    printf("\nName: %s | Age: %d\n", object.name, object.age);

    return 0;
}

void save(int num, char path[100], person (*p_object)[num]) {
    FILE *file = fopen(path, "w+");
    fwrite(p_object, sizeof(person), num, file);
    fclose(file);
}

person load(char path[100], int index) {
    person object;
    FILE *file = fopen(path, "r");
    fseek(file, (long) sizeof(person) * index, SEEK_SET);
    fread(&object, sizeof(person), 1, file);
    fclose(file);

    return object;
}

请注意,最好使用现有函数freadfwrite,而不是自己实现。

这将使您的代码更简单、更直接。

另外,您对fread 的实现不正确,因为 EOF 可能出现在那里,因为您正在写入二进制数据,您需要读取结构的整个大小来加载它。

【讨论】:

  • 指出代码的具体问题以及您的代码如何避免这种情况会很有用。
  • 更新了“bug”部分,我的实现改变了一些东西,只是为了改进代码,而不仅仅是修复它。
  • 非常感谢您对“fwrite”和“fread”函数的回答。我不知道这个。比我自己实现的方便
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 2022-01-13
  • 2022-11-16
  • 2017-12-06
相关资源
最近更新 更多