繁体   English   中英

fread / fwrite无法正常工作

[英]fread/fwrite not working as expected

因此,我试图编写一个具有学生记录数据库的ac文件,该文件一旦运行,就应该从二进制文件中读取学生记录并将其添加到链接列表中:student结构如下:

typedef struct student {
    char lname[10], initial, fname[10];
    unsigned long SID;
    float GPA;

    struct student* next; /* pointer to the next student record */   
} studentList;

我正在为数据使用单个链接列表,如果我使用fscanf读写数据,我的代码可以正常运行。 但是,一旦我开始使用fwrite和fread,则每次我的程序加载时,都无法正确地从文本文件加载数据,当我检查二进制文件时,似乎其中包含数据。 这是我的加载和写入数据功能:

void printRecords() {
    FILE *fPointer = fopen("data.bin", "w");
    studentList *newStudent = head;
    while (newStudent != NULL) { /*Loop through linked list starting from head node*/
        fwrite(&newStudent, sizeof(newStudent), 1, fPointer);

        newStudent = newStudent->next;
    }
}

void loadRecords() {
    studentList *cStudent;
    FILE *fPointer = fopen("data.bin", "r");
    int counter = 0;
    int x = 0;
    int n = 0;
    while (n != 0) {
        printf("test\n");
        if (fPointer == NULL) {
            break;
        }
        cStudent = (studentList *)malloc(sizeof(studentList));
        n = fread(&cStudent, sizeof(cStudent), 1, fPointer);
        x = cStudent->GPA;
        printf("%d\n", x);
        if (feof(fPointer)) { break; }
        if (counter == 0) {
            head = cStudent;
            temp = (studentList *)malloc(sizeof(studentList));
            temp = cStudent;
            counter++;
        }

        temp->next = (studentList *)malloc(sizeof(studentList));
        temp->next = cStudent;
        temp = temp->next;
    }
    fclose(fPointer);
}

所以我在做错什么,因为它现在什么都没读到我的列表中,似乎在写,但是不确定它是否写正确的数据,我花了很长时间试图弄清楚这一点,并一直坚持下去暂时先感谢一下。

读取对c中的二进制文件的写入

FILE   *fPointer=fopen("data.bin","wb");  //to write file
FILE *fPointer=fopen("data.bin","rb");    //to read file

您的代码有多个问题。

printRecords有问题:

  • 您应该使用二进制模式。
  • 您可以编写指针的内容和一些不确定的内容,而不用写指针指向的内容。 这实际上是未定义的行为。
  • 您忘记了关闭文件。
  • next成员写入文件的值是没有意义的。 写入相同的记录可能会为不同的运行产生不同的文件内容。

这是一个更正的版本,它返回写入的记录数;如果无法打开文件,则返回-1:

int printRecords(void) {
    FILE *fPointer = fopen("data.bin", "wb");
    studentList *sp;
    int n = 0;

    if (fPointer == NULL)
        return -1;

    /* Loop through linked list starting from head node */
    for (sp = head; sp != NULL; sp = sp->next) {
        n += fwrite(sp, sizeof(newStudent), 1, fPointer);
    }
    fclose(fPointer);
    return n;
}

loadRecords还有更多问题:

  • 二进制模式也应该使用。
  • 您测试文件结尾的方式不正确。
  • 链接记录的方式也不起作用。

这是loadRecords的更正版本,它返回读取的记录数;如果无法打开文件,则返回-1:

int loadRecords(void) {
    studentList student, *newsp, *sp;
    FILE *fPointer = fopen("data.bin", "rb");
    int n = 0;

    if (fPointer == NULL)
        return -1;

    while (fread(&student, sizeof(student), 1, fPointer) == 1) {
        n++;
        student.next = NULL;  // value read from file is meaningless
        newsp = malloc(sizeof(studentList));
        *newsp = student;
        if (head == NULL) {
            head = newsp;
        } else {
            /* append the new record to the list */
            for (sp = head; sp->next; sp = sp->next)
                continue;
            sp->next = newsp;
        }
    }
    fclose(fPointer);
    return n;
}

请注意,以这种方式将二进制数据存储到文件系统是不可移植的。 整数和浮点数的表示可能在一个平台与另一个平台之间以及结构成员的对齐方式上有所不同,尤其是next指针,该指针无论如何在文件中都是无用的。 仅应在相同的平台上以及使用编写该文件的程序来读取该文件,这使其成为备份或持久存储的不佳选择。

文件写入功能存在问题,主要是数据指针和大小:

void printRecords(){
    FILE *fPointer = fopen("data.bin","wb");    // add "b" mode (MSVC)
    if (fPointer == NULL)                       // check file opened
        exit(1);                                // or report "Cannot open file"
    studentList *newStudent = head;
    while(newStudent !=NULL)
    {
        fwrite(newStudent, sizeof(*newStudent), 1, fPointer);   // remove the & and add a *
        newStudent = newStudent->next;
    }
    if (fclose(fPointer))                       // close the file
        exit(1);                                // or report "Failed to close file"
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM