C语言 读/写结构到文件 - c

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15643870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:50:10  来源:igfitidea点击:

read / write structures to file - c

cfile-io

提问by Josephine

I'm working on creating a student database in C. The final thing I need to be able to do read and write the database I create to a file. So I've already got an array full of pointers to student structures, and I need to write it to a file. Once I have it written, I need to be able to read it back into my array as well.

我正在用 C 语言创建一个学生数据库。最后我需要能够读取我创建的数据库并将其写入文件。所以我已经得到了一个充满指向学生结构的指针的数组,我需要将它写入一个文件。一旦我写好了它,我还需要能够将它读回我的数组。

I'm really not sure how to do it though. This is my struct:

我真的不知道该怎么做。这是我的结构:

typedef struct student Student;
struct student 
{
    char name[300];
    int age;
    char course1[300];
    char course2[300];
    char remarks[300];
};

Student *Data[30];

And these are the functions I've written to work with file:

这些是我编写的用于处理文件的函数:

void writeDisk()
{
    FILE *file = fopen("disk.dat", "ab");
    fwrite(&Data, sizeof(Student), count, file);
    fclose(file);
}

void loadDisk()
{
    FILE *file = fopen("disk.dat", "rb");
    if (file != NULL)
    {
        fread(&Data, sizeof(Student), count, file);
        fclose(file);       
    }
}

void emptyDisk()
{

    FILE *file = fopen("disk.dat", "rw");
    fopen("disk.dat", "wb");

}

I can see that the size of my disk.dat file changes when I write to it, and it goes to zero when I call empty, but loading does not work at all. If the student array in my program is zero, it just stays at zero when I call load and try to display it, but if there is something in the array, I get a segmentation fault when I call load and then try to display it.

我可以看到我的 disk.dat 文件的大小在我写入时发生了变化,当我调用 empty 时它变为零,但加载根本不起作用。如果我程序中的 student 数组为零,则在我调用 load 并尝试显示它时它只是保持为零,但是如果数组中存在某些内容,则在调用 load 然后尝试显示时会出现分段错误。

I may be doing this entirely wrong. I'm really not sure what I'm doing. I was thinking that I could just write the whole array to a file, but I'm not sure that's true. I was just wondering if someone could look at this and let me know where I'm going wrong.

我这样做可能完全错误。我真的不确定我在做什么。我在想我可以将整个数组写入一个文件,但我不确定这是真的。我只是想知道是否有人可以看看这个并让我知道我哪里出错了。

EDIT

编辑

I've edited my code to look like this:

我已经编辑了我的代码,如下所示:

void writeDisk()
{
    int i = 0;
    FILE *file = fopen("disk.dat", "ab");

    for(i; i <count; i++)
    {
        fwrite(Data[i], sizeof(Student), 1, file);  
    }

    fclose(file);
}

void loadDisk()
{
    char buffer[300];
    int i = 0;

    clearData();

    FILE *file = fopen("disk.dat", "rb");
    while(Data[i] != NULL)
{
    Data[i] = malloc(sizeof(Student));
    fread(Data[i], sizeof(Student), 1, file);
    i++;
}

    fclose(file);       
}

This still doesn't work though. The write seems to work better,but I don't see it writing the age of the student over to the file. The clearData() function in the load file just clears anything that's in the Data array to begin with, so that we can have a clean slate to read the file into.

但这仍然不起作用。写入似乎效果更好,但我没有看到它将学生的年龄写入文件。加载文件中的 clearData() 函数只是清除 Data 数组中的所有内容,以便我们可以有一个干净的平板来读取文件。

回答by Dan

I believe instead of

我相信而不是

Student *Data[30];

You want

你要

Student Data[30];

Because the first one is an array of pointers, while the second one is an array of the struct you want.

因为第一个是指针数组,而第二个是你想要的结构数组。

When you write

当你写

fread(&Data, sizeof(Student), count, file);

It reads the data from the file right into the location of Data. It looks like you want to read and write the actual structs, so you have to put them directly into the array, as opposed to using pointers.

它将文件中的数据直接读取到Data. 看起来您要读取和写入实际的结构体,因此您必须将它们直接放入数组中,而不是使用指针。

回答by slezica

I think this is the culprit:

我认为这是罪魁祸首:

Student *Data[30];

That's an array of pointers to Studentstructures. There is no storage allocated for actual Students.

这是一个指向Student结构指针数组。没有为实际的Students.

Remove the *, throughout the rest of the code you seem to properly use Dataas if it was a plain array, so it should need no modification.

删除*, 在您似乎正确使用的其余代码中,就好像Data它是一个普通数组一样,因此它不需要修改。

EDITon an unrelated note, you can declare a structure and its alias on the same statement, like this:

编辑无关的注释,您可以在同一语句中声明结构及其别名,如下所示:

typedef struct {
    ...
} Student;

回答by DoxyLover

If Data is indeed an array of pointers to your structures, then what you are saving is just the pointers and not your actual data. In fact, you should never save actual pointers as the next time you run, malloc may return different pointers for storing your data.

如果 Data 确实是指向您的结构的指针数组,那么您保存的只是指针而不是您的实际数据。事实上,您永远不应该在下次运行时保存实际的指针,malloc 可能会返回不同的指针来存储您的数据。

What you want to do, for saving, is to iterate over your array and write the actual structure data to the file, something like:

为了保存,您想要做的是迭代数组并将实际结构数据写入文件,例如:

for (i = 0; i < numberOfStudents; i++) {
    fwrite(Data[i], sizeof (Student), 1, file);
}

For restoring, you'll need to loop over the students, malloc storage and read in the structure, and then set the Data pointer, something like:

为了恢复,您需要遍历学生、malloc 存储并读取结构,然后设置数据指针,例如:

for (i = 0; i < numberOfStudents; i++) {
    Student *p = malloc(sizeof (Student));
    fread(p, sizeof (Student), 1, file);
    Data[i] = p;
}

Also, in general, you should check the return values from fopen, fread, fwrite, and fclose to detect errors.

此外,一般而言,您应该检查 fopen、fread、fwrite 和 fclose 的返回值以检测错误。