简体   繁体   English

C-如何从二进制文件中读取链接列表?

[英]C - How to Read in a Linked List from a Binary File?

I need some assistance with my code. 我的代码需要一些帮助。 I've created the function for writing the linked list to a binary file. 我已经创建了用于将链接列表写入二进制文件的函数。 Now I'm trying to read in a linked list from a binary file that my write function has outputted. 现在,我尝试从我的写函数已输出的二进制文件中读取链表。 My attempt at trying to read in the binary file and creating the link segfaults. 我试图读取二进制文件并创建链接段错误的尝试。 This is my attempt below. 这是我在下面的尝试。

What am I doing wrong? 我究竟做错了什么?

void readlist(struct link **headptr) {                                                                                                                      
    FILE *text = fopen("numbers.bin", "rb");                                                                                                                 
    struct link *head = *rootptr;                                                                                                                                                                                                                                                           


   while (head->next != NULL) {                                                                                                                             
       struct link *newlink = (struct link*) malloc(sizeof(struct link));                                                                                    
       fread(&newlink->val, sizeof(int), 1, text);                                                                                                       
       head->next = newlink;                                                                                                                                 
       head = newlink;                                                                                                                                       
    }                                                                                                                                                        
       fclose(text);   
}                                                                                                                                                                                                                                                                              

I hope this code is helpful to you. 我希望这段代码对您有所帮助。 if you use a global variable headptr, it will be more simple. 如果使用全局变量headptr,它将更加简单。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>
#include <fcntl.h>

#define LISTSAVE "numbers.bin"

struct link {
    int val ;
    struct link *next ;
} ;

void print_list(struct link *headptr) {
    struct link *tmp = headptr->next ;
    int cnt=0 ;
    printf("---list start----\n") ;
    while(tmp) {
        printf("%d ", tmp->val) ;
        cnt++ ;
        tmp=tmp->next ;
    }
    printf("\n%d items\n", cnt) ;
    printf("---list end----\n") ;
}


void add_first(struct link *headptr, int val) {
    struct link *tmp = malloc(sizeof(struct link)) ;
    tmp->val = val ;
    tmp->next = headptr->next ;
    headptr->next = tmp ;
}

void add_tail(struct link *headptr, int val) {
    struct link *tmp = headptr;
    struct link *tmp2 = malloc(sizeof(struct link)) ;
    tmp2->val = val ;
    tmp2->next=NULL ;

    while(tmp->next) {
        tmp=tmp->next ;
    }
    tmp->next=tmp2 ;
}

void del_list(struct link *headptr) {
    struct link *tmp = headptr->next ;
    struct link *tmp2 = NULL ;
    while (tmp) {
        tmp2=tmp->next ;
        free(tmp);
        tmp=tmp2 ;
    }
    headptr->next=NULL ;
}

void save_list(struct link *headptr) {
    FILE *text = fopen(LISTSAVE, "wb+") ;
    struct link *tmp=headptr->next ;
    int cnt=0 ;

    if ( text==NULL || headptr==NULL ) {
        printf("filed to save.\n") ;
        return ;
    }
    while (tmp!=NULL ) {
        cnt++ ;
        fwrite(&tmp->val, sizeof(int), 1, text) ;
        tmp = tmp->next ;
    }
    fclose(text) ;
    printf("write %d items ok\n", cnt) ;
}

void read_list(struct link *headptr) {
    FILE *text = fopen(LISTSAVE, "rb") ;
    int val ;
    int cnt=0 ;
    while( fread(&val, sizeof(int), 1, text) > 0 ) {
        add_tail(headptr, val) ;
        cnt++ ;
    }
    fclose(text);
    printf("read %d items ok\n", cnt) ;
}


int main() {
    struct link head ;
    head.val=0 ;
    head.next=NULL ;

    add_first(&head, 40) ;
    add_first(&head, 30) ;
    add_first(&head, 20) ;
    add_first(&head, 10) ;
    add_tail(&head, 50) ;
    add_tail(&head, 60) ;

    print_list(&head) ;
    printf("--save list\n") ;
    save_list(&head) ;
    del_list(&head) ;

    printf("--read list\n") ;
    read_list(&head) ;
    print_list(&head) ;
    del_list(&head) ;

    return 0 ;
}

the output is this 输出是这个

---list start----
10 20 30 40 50 60 
6 items
---list end----
--save list
write 6 items ok
--read list
read 6 items ok
---list start----
10 20 30 40 50 60 
6 items
---list end----

You can't save a generic linked list to a file. 您无法将通用链接列表保存到文件。 For it to work, you'd need to be in full control of memory allocations including the addresses you get. 为了使其正常工作,您需要完全控制内存分配,包括获得的地址。 Generally, you won't be. 通常,您不会。

If you overlay the linked list over a single buffer, then you can save it by translating pointers to indices and back (or just by using indices instead of pointers), but generically, you cannot save a linked list to disk, free the memory (including by exiting), reload, and then expect the saved pointers to work. 如果将链接列表覆盖在单个缓冲区上,则可以通过将指针转换为索引然后返回(或仅通过使用索引而不是指针)来保存它,但是一般来讲,您不能将链接列表保存到磁盘上,而要释放内存( (包括退出),重新加载,然后期望保存的指针起作用。

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

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