繁体   English   中英

如何获取文件内结构的指针

[英]How to get the pointer of a struct inside a file

我想在文件中添加轮渡作为节点并跟踪前一个和下一个指针,目的是创建一个循环双向链接列表。 船名作为参数写入到主function的终端中。

function添加渡轮代码:

int Register_ferry(char *f){
FILE *pFile;
pFile = fopen("Ferries.txt","a+");
if(pFile!=0){
    FILE *dFile;
    dFile = fopen("Ferries.txt","r+");
    ferry *new_node=(ferry*)malloc(sizeof(ferry));
    ferry *new_node2=(ferry*)malloc(sizeof(ferry));
    fseek(pFile,0,SEEK_END);
    if(ftell(pFile)==0){
        new_node->fld=atoi(f);
            new_node->next=new_node;
        new_node->prev=new_node;
        printf("CURR: %p\n",new_node);
        printf("NEXT: %p\n",new_node->next);
        printf("PREV: %p\n",new_node->prev);
    }
    else if(ftell(pFile)==8){
        new_node->fld=atoi(f);
        fseek(dFile,0,SEEK_SET);
        fread(new_node2,sizeof(new_node2),1,dFile);
        new_node->next=new_node2;
        new_node->prev=new_node2;
        new_node2->next=new_node;
        new_node2->prev=new_node;
        fwrite(new_node2, sizeof(new_node),1,dFile);
            printf("CURR: %p\n",new_node);
        printf("NEXT: %p\n",new_node->next);
        printf("PREV: %p\n",new_node->prev);    
    }
    else{   
        new_node->fld=atoi(f);
        fseek(dFile,-8,SEEK_END);
        fread(new_node2,sizeof(new_node2),1,dFile);
            new_node->prev=new_node2;
        fseek(dFile,0,SEEK_SET);
        fread(new_node2,sizeof(new_node2),1,dFile);
        new_node->next=new_node2;
        printf("CURR: %p\n",new_node);
        printf("NEXT: %p\n",new_node->next);
        printf("PREV: %p\n",new_node->prev);    
    }
    fwrite(new_node, sizeof(new_node), 1, pFile);
    fclose(pFile);
    free(new_node);
    free(new_node2);
}
return 0;} 

主要代码:

 int main(int narg , char* argv[]){
 if (strcmp(argv[1], "R")==0)
 {  
    Register_ferry(argv[2]);
     }
 return 0;} 

渡轮的结构:

typedef struct ferry{
int fld;
struct ferry *next;
struct ferry *prev;
}ferry;

调用程序的照片: 在此处输入图像描述

经过一些尝试,我意识到使用 printf 命令我不会获得文件内节点的指针,而是我使用 function Z224EDA3DC1D26B208EDCC3A08D3175F2 创建的节点的指针。 所以我的问题是我应该如何获取文件内节点的指针以保持循环双向链表应有的状态?

最后,由于某种原因,我的 function 和第一个 if 没有以相应的“}”结尾,但由于某种原因仍然很重要。 但是终端没有提示任何错误,所以有点奇怪。

我认为将您的渡轮数据包装到链表结构中会更好。 然后,您可以将所有渡轮保存在一个平面文件中,并将它们链接到另一个文件中,而无需将二进制指针保存到文件中。

typedef struct {
    int fld;
    char name[20];
    /* Some other fields */
} ferry;

// From https://stackoverflow.com/a/18582440/2928168 :
typedef struct list {
    struct ferry *node;
    struct list *prev;
    struct list *next;
} list;

然后,您可以使用freadfwrite通过循环列表来加载渡轮数据并将其保存到文件中。 有关订单的数据,需要使用其他技术保存在不同的文件中,或者作为第一个文件的 header。 例如,为每个节点保存一个整数三元组,指向 3 个节点的索引:当前、上一个和下一个。

完整示例:

  • memory中的循环链表,文件中的平面链表
  • 只有一个结构来定义数据和链接(指针)
  • 只有一个文件(不需要标题或额外文件)
  • 不要写和读指针,只有数据
  • 在读取期间计算指针
  • 为每个节点分配 memory
  • 免费所有声称的 memory
  • 添加程序参数以仅读取所有渡轮并退出
  • 添加了程序参数以允许保存名称
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct ferry {
    int fld;
    char name[20];
    struct ferry *next;
    struct ferry *prev;
}ferry;

/* Full size used for malloc, without pointers for read/write */
#define FERRY_SIZE (sizeof(ferry))
#define FERRY_SIZE_WITHOUT_POINTERS (FERRY_SIZE - (sizeof(ferry*)*2))

#define FILE_DATA "Ferries.txt"

int write_ferries(ferry*first_node) {
    FILE *data_file;
    int count = 0;

    /* We will modify the pointer to loop over the linked list */
    ferry*node = first_node;

    data_file = fopen(FILE_DATA,"w");
    do {
        count++;
        fwrite(node, FERRY_SIZE_WITHOUT_POINTERS,1,data_file);
        node = node->next;
    } while(node != first_node);

    fclose(data_file);

    return count;
}

ferry* read_ferries() {
    FILE *data_file;
    int data_size;
    int num_nodes;
    ferry*first_node = NULL, *prev_node = NULL;
    int i;

    /* Get file size */
    /* If file does not exists or its size is zero, return NULL */
    data_file = fopen(FILE_DATA,"r+");
    if(data_file == NULL) {
        return NULL;
    }

    fseek(data_file,0,SEEK_END);
    data_size = ftell(data_file);

    if(data_size == 0) {
        fclose(data_file);
        return NULL;
    }

    /* Calculate num of nodes using file size and struct size */
    num_nodes = data_size / FERRY_SIZE_WITHOUT_POINTERS;
    fseek(data_file,0,SEEK_SET);

    /* Read all ferries and assign prev/next following file order */
    for(i = 0; i < num_nodes; i++) {
        ferry *node = malloc(FERRY_SIZE);
        fread(node,FERRY_SIZE_WITHOUT_POINTERS,1,data_file);

        if(first_node == NULL) {
            first_node = node;
        }

        /* Assign prev/next using order in file */
        if(i > 0) {
            node->prev = prev_node;
            prev_node->next = node;
        }

        prev_node = node;
    }

    fclose(data_file);

    /* Link first and last nodes */
    prev_node->next = first_node;
    first_node->prev = prev_node;

    return first_node;
}

int free_all_nodes(ferry*first_node) {
    ferry*last_node = first_node->prev;
    ferry*node = first_node;

    do {
        node = node->next;
        free(node->prev);
    } while(node != last_node);
}

int Register_ferry(char *fld, char *name){
    /* Generate the new node */
    ferry *new_node = malloc(FERRY_SIZE);
    new_node->fld = atoi(fld);
    if(name != NULL && strlen(name) > 0) {
        strcpy(new_node->name, name);
    }

    /* Read all ferries, get the first */
    ferry*first_node = read_ferries();

    if(first_node == NULL) {
        /* If this is the first node */
        new_node->prev = new_node;
        new_node->next = new_node;
        write_ferries(new_node);

        printf("CURR: %p\n",new_node);
        printf("NEXT: %p\n",new_node->next);
        printf("PREV: %p\n",new_node->prev);

        /* Free single node memory */
        free(new_node);
    }
    else {
        printf("first_node CURR: %p\n",first_node);
        printf("first_node NEXT:%p\n",first_node->next);
        printf("first_node PREV:%p\n",first_node->prev);

        /* Link the new node */
        new_node->prev = first_node->prev;
        new_node->next = first_node;
 
        /* Update the first node to point its prev to the new one */
        first_node->prev = new_node;
 
        /* Update the last node to point its next to the new one */
        new_node->prev->next = new_node;

        /* Save the entire list */
        write_ferries(first_node);

        printf("CURR: %p\n",new_node);
        printf("NEXT: %p\n",new_node->next);
        printf("PREV: %p\n",new_node->prev);

        /* Free all allocated memory for nodes */
        free_all_nodes(first_node);
    }

    return 0;
}

int show_ferries(void) {
    ferry*first_node = read_ferries();
    ferry*node = first_node;
    int count = 0;

    if(first_node == NULL) {
        printf("No ferries yet.\n");
        return 0;
    }

    do {
        count++;
        printf("Ferry %d: %d - %s\n", count, node->fld, node->name);
        node = node->next;
    } while(node != first_node);

    free_all_nodes(first_node);

    return count;
}

int main(int argc, char*argv[]) {
    if (strcmp(argv[1], "R") == 0) {  
        Register_ferry(argv[2], argv[3]);
    }
    if (strcmp(argv[1], "L") == 0) {  
        show_ferries();
    }

    return 0;
}

暂无
暂无

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

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