Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从二进制文件读取/写入链接节点_C_Struct_Linked List - Fatal编程技术网

C 从二进制文件读取/写入链接节点

C 从二进制文件读取/写入链接节点,c,struct,linked-list,C,Struct,Linked List,我在读取包含链接节点的二进制文件时遇到问题 代码如下: lib1.c struct my_stack_node { void *data; struct my_stack_node *next; }; struct my_stack { int size; struct my_stack_node *first; }; int my_stack_write(struct my_stack *stack, char *filename){ int count = 0; struct my_st

我在读取包含链接节点的二进制文件时遇到问题

代码如下:

lib1.c

struct my_stack_node {
void *data;
struct my_stack_node *next;
};

struct my_stack {
int size;
struct my_stack_node *first;
};

int my_stack_write(struct my_stack *stack, char *filename){
int count = 0;
struct my_stack_node *aux;
FILE *file = fopen(filename, "wb");
if(stack->first != NULL){
    aux = stack->first;
    count++;
    while(aux->next != NULL){
        fwrite(&aux ,sizeof(aux), 1, file);
        aux = aux->next;
        count++;
    }
}
fwrite(&stack, sizeof(stack), 1, file); //Escriure stack
fclose(file);
return count;
}    

struct my_stack *my_stack_read(char *filename){
struct my_stack *stackRead;
struct my_stack_node *stackNode;
FILE *file = fopen(filename, "rb");

if(!file){
    puts("Impossible obrir el fitxer");
    return NULL;
}else{
    int primerInici = 0;

    while(!feof(file)){
        if(primerInici == 0){
            stackRead = (struct my_stack*) malloc(sizeof(struct my_stack));
            fread(stackRead, sizeof(stackRead), 1, file);
            primerInici = 1;
        }else{
            //Crear nou node i llegir-lo del fitxer
            stackNode = (struct my_stack_node*) malloc(sizeof(struct my_stack_node));
            fread(stackNode, sizeof(stackNode), 1, file);
            //Afegir node a la pila
            stackNode->next = stackRead->first;
            stackRead->first = stackNode;
        }
    }
    fclose(file);
    return stackRead;
}

}
main.c

 struct my_data {
   int val;
   char name[60];
 };


int main() {
struct my_stack *s, *t, *u;
struct my_data *data, *data1, *data2;
//...more code
    u = my_stack_read("/tmp/my_stack.data");
if (! u) {
    puts("Error in my_stack_read (u)");
    exit(1);
}

if (my_stack_len(s) != my_stack_len(u)) {
    puts("Stacks s and u don't have the same len");
    exit(1);
}

// Test we can free the data and compare stacks s and u
while((data1 = my_stack_pop(s))) {
    data2 = my_stack_pop(u);
    if (! data2 || data1->val != data2->val || my_strcmp(data1->name, data2->name)) {
        printf("Data in s and u are not the same: %d <> %d\n", data1->val, data2->val);
        exit(1);
    }
    free(data1);
    free(data2);
}
//...more code 
puts("All tests passed");
return 0;

}
struct my_数据{
int-val;
字符名[60];
};
int main(){
结构my_堆栈*s,*t,*u;
结构my_data*data、*data1、*data2;
//…更多代码
u=my_stack_read(“/tmp/my_stack.data”);
如果(!u){
puts(“我的_堆栈中的错误_读取(u)”;
出口(1);
}
如果(my_stack_len(s)!=my_stack_len(u)){
看跌期权(“s和u没有相同的len”);
出口(1);
}
//测试我们可以释放数据并比较堆栈s和u
而((data1=my_stack_pop){
数据2=我的堆栈弹出(u);
如果(!data2 | | data1->val!=data2->val | | my|u strcmp(data1->name,data2->name)){
printf(“s和u中的数据不相同:%d%d\n”,数据1->val,数据2->val);
出口(1);
}
免费(数据1);
免费(数据2);
}
//…更多代码
看跌期权(“所有测试通过”);
返回0;
}
执行的结果是:

堆栈长度:100

s和u中的数据不相同:22145808 22134800

正确的结果应该是:

所有通过的测试都存在问题(在我的\u堆栈\u写入中):

您正在写入指针
aux
。不是由
aux
指向的结构。无论是
数据
所指的数据,它都是重要的部分

所以。想象你有这样的东西:

my_stack  { first=0x100 }
at memoryPosition 0x100 we have : my_stack_node { data=0x200; next=0x300 }
at memoryPosition 0x300 we have : my_stack_node { data=0x500; next=0x600 }
at memoryPosition 0x600 we have : my_stack_node { data=0x700; next=NULL }
对于该结构,您的程序正在写入:0x100、0x300
您正在写入构成链接列表的节点的内存地址。您缺少最后一个节点,这是另一种错误。
但这是没有用的。下次运行程序时,节点可能位于不同的内存地址中,因此保存它们没有意义。它是动态内存,每次运行程序时,它可能位于不同的位置

你应该写的是你的链表上列出的数据

同样的错误几乎在整个程序中重复

如何正确写入链表中包含的数据:

void writeStack(struct my_stack *stack, const char *filename)
{
  struct my_stack_node *aux;
  FILE *file = fopen(filename, "wb");
  if ( file==NULL )
  {
    fprintf( stderr, "Could not open %s for writting.\n", filename );
    exit(1);
  }
  if (stack != NULL)
  {
    aux = stack->first;
    while(aux != NULL)
    {
      //   aux->data is of type void*
      //   Assuming that aux->data contains a struct my_data
      //   Most likely it would be better to redefine data as having
      // type struct my_data*
      fwrite(aux->data ,sizeof(struct my_data), 1, file);
      aux = aux->next;
    }
  }
  fclose(file);
}    
这里我们遍历列表中的所有节点。
对于每一个,我们都将包含的数据写入其中。
注意
fwrite(aux->data,
如何写入
aux->data
所指向的数据,这是正确的。
fwrite(&aux,
将写入
aux
中包含的内存地址,这不太可能是正确的。
fwrite(&aux->data,
将写入
aux->data
中包含的内存地址,这也不太可能是正确的


由您添加计数代码并编写读取函数。

您只读取和写入堆栈本身,而不是其节点的有效负载,它存储在voa
void*
指针中

节点本身不携带有意义的信息。或者跨会话有意义的信息,而是:
data
next
指针仅在写入数据的会话中有效

堆栈本质上是一个线性数据结构。不存储节点,而是将堆栈数据存储为
数据
成员数组。当您读入它们时,用新分配的节点和读取的
数据
字段构建一个列表

堆栈使用
void*
指针来允许各种数据类型。因此,必须找到一种方法来告诉读写方法如何写入或读取数据

您可以提供一个回调函数,在其中传递打开的文件。如果需要,这种回调可以处理复杂的数据结构,如负载

编辑:下面的代码演示了如何使用自定义函数序列化堆栈以进行读写。对称回调应将数据写入文件并读取数据。读取函数可分配堆栈拥有的内存。用户必须确保释放内存

回调可以返回负数以指示错误。要读取的堆栈不必为空。读取数据只是被推送到堆栈中

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

#define die(...) exit((printf(__VA_ARGS__), putchar('\n'), 1));

typedef struct Stack Stack;
typedef struct SNode SNode;

struct SNode {
    void *data;
    SNode *next;
};

struct Stack {
    SNode *head;
};

/*
 *      Core stack functions
 */
void stack_push(Stack *st, void *data)
{
    SNode *sn = malloc(sizeof(*sn));

    sn->data = data;
    sn->next = st->head;
    st->head = sn;
}

void *stack_pop(Stack *st)
{
    void *data;
    SNode *sn;

    if (st->head == NULL) die("Undeflow");

    sn = st->head;
    data = sn->data;
    st->head = sn->next;

    free(sn);
    return data;    
}

int stack_empty(const Stack *st)
{
    return (st->head == NULL);
}

/*
 *      Stack write function with custom callback
 */
int stack_write(const Stack *st, const char *filename,
    int (*func)(FILE *f, const void *data))
{
    const SNode *sn = st->head;
    size_t count = 0;

    FILE *f = fopen(filename, "wb");
    if (f == NULL) return -1;
    fwrite(&count, 1, sizeof(count), f);

    while (sn) {
        if (func(f, sn->data) < 0) {
            fclose(f);
            return -1;
        }
        count++;
        sn = sn->next;
    }

    fseek(f, SEEK_SET, 0);
    fwrite(&count, 1, sizeof(count), f);    
    fclose(f);

    return count;
}

/*
 *      Stack read function with custom callback
 */
int stack_read(Stack *st, const char *filename,
    int (*func)(FILE *f, void **data))
{
    size_t count = 0;
    size_t i;

    FILE *f = fopen(filename, "rb");
    if (f == NULL) return -1;
    fread(&count, 1, sizeof(count), f);

    for (i = 0; i < count; i++) {
        void *p;

        if (func(f, &p) < 0) {
            fclose(f);
            return -1;
        }

        stack_push(st, p);
    }

    fclose(f);
    return count;
}


/*
 *      Custom data struct with read/write functions
 */
struct my_data {
    int val;
    char name[60];
};

int my_data_write(FILE *f, const void *data)
{
    if (fwrite(data, sizeof(struct my_data), 1, f) < 1) return -1;
    return 0;
}

int my_data_read(FILE *f, void **data)
{
    *data = malloc(sizeof(struct my_data));

    if (*data == NULL) return -1;

    if (fread(*data, sizeof(struct my_data), 1, f) < 1) {
        free(data);
        return -1;
    }

    return 0;
}

/*
 *      Example client code
 */
int main()
{
    Stack s = {NULL};
    Stack t = {NULL};

    struct my_data aa = {23, "Alice Atkinson"};
    struct my_data bb = {37, "Bob Bates"};
    struct my_data cc = {28, "Carol Clark"};

    stack_push(&s, &aa);
    stack_push(&s, &bb);
    stack_push(&s, &cc);

    stack_write(&s, "kk", my_data_write);

    while (s.head) stack_pop(&s);

    stack_read(&t, "kk", my_data_read);

    while (t.head) {
        struct my_data *p = stack_pop(&t);

        printf("%4d '%s'\n", p->val, p->name);
        free(p);
    }

    return 0;    
}
#包括
#包括
#定义die(…)exit((printf(_VA_ARGS),putchar('\n'),1));
typedef结构堆栈;
typedef结构SNode SNode;
结构势垒{
作废*数据;
斯诺德*下一个;
};
结构堆栈{
斯诺德*头;
};
/*
*核心堆栈函数
*/
无效堆栈推送(堆栈*st,无效*数据)
{
SNode*sn=malloc(sizeof(*sn));
序列号->数据=数据;
sn->next=st->head;
st->head=sn;
}
void*stack_pop(stack*st)
{
作废*数据;
SNode*sn;
如果(st->head==NULL)模具(“未流动”);
sn=st->head;
数据=序列号->数据;
st->head=sn->next;
免费(sn);
返回数据;
}
int stack_empty(常量堆栈*st)
{
返回(st->head==NULL);
}
/*
*具有自定义回调的堆栈写入函数
*/
int stack_write(常量stack*st,常量char*filename,
int(*func)(文件*f,常量void*data))
{
const SNode*sn=st->head;
大小\u t计数=0;
文件*f=fopen(文件名,“wb”);
如果(f==NULL)返回-1;
fwrite(&count,1,sizeof(count),f);
while(sn){
if(函数(f,序号->数据)<0){
fclose(f);
返回-1;
}
计数++;
sn=sn->next;
}
fseek(f,SEEK_集,0);
fwrite(&count,1,sizeof(count),f);
fclose(f);
返回计数;
}
/*
*具有自定义回调的堆栈读取函数
*/
int stack_read(stack*st,const char*filename,
int(*func)(文件*f,无效**数据))
{
大小\u t计数=0;
尺寸i;
FILE*f=fopen(文件名为“rb”);
如果(f==NULL)返回-1;
fread(&count,1,sizeof(count),f);
对于(i=0;i#include <stdlib.h>
#include <stdio.h>

#define die(...) exit((printf(__VA_ARGS__), putchar('\n'), 1));

typedef struct Stack Stack;
typedef struct SNode SNode;

struct SNode {
    void *data;
    SNode *next;
};

struct Stack {
    SNode *head;
};

/*
 *      Core stack functions
 */
void stack_push(Stack *st, void *data)
{
    SNode *sn = malloc(sizeof(*sn));

    sn->data = data;
    sn->next = st->head;
    st->head = sn;
}

void *stack_pop(Stack *st)
{
    void *data;
    SNode *sn;

    if (st->head == NULL) die("Undeflow");

    sn = st->head;
    data = sn->data;
    st->head = sn->next;

    free(sn);
    return data;    
}

int stack_empty(const Stack *st)
{
    return (st->head == NULL);
}

/*
 *      Stack write function with custom callback
 */
int stack_write(const Stack *st, const char *filename,
    int (*func)(FILE *f, const void *data))
{
    const SNode *sn = st->head;
    size_t count = 0;

    FILE *f = fopen(filename, "wb");
    if (f == NULL) return -1;
    fwrite(&count, 1, sizeof(count), f);

    while (sn) {
        if (func(f, sn->data) < 0) {
            fclose(f);
            return -1;
        }
        count++;
        sn = sn->next;
    }

    fseek(f, SEEK_SET, 0);
    fwrite(&count, 1, sizeof(count), f);    
    fclose(f);

    return count;
}

/*
 *      Stack read function with custom callback
 */
int stack_read(Stack *st, const char *filename,
    int (*func)(FILE *f, void **data))
{
    size_t count = 0;
    size_t i;

    FILE *f = fopen(filename, "rb");
    if (f == NULL) return -1;
    fread(&count, 1, sizeof(count), f);

    for (i = 0; i < count; i++) {
        void *p;

        if (func(f, &p) < 0) {
            fclose(f);
            return -1;
        }

        stack_push(st, p);
    }

    fclose(f);
    return count;
}


/*
 *      Custom data struct with read/write functions
 */
struct my_data {
    int val;
    char name[60];
};

int my_data_write(FILE *f, const void *data)
{
    if (fwrite(data, sizeof(struct my_data), 1, f) < 1) return -1;
    return 0;
}

int my_data_read(FILE *f, void **data)
{
    *data = malloc(sizeof(struct my_data));

    if (*data == NULL) return -1;

    if (fread(*data, sizeof(struct my_data), 1, f) < 1) {
        free(data);
        return -1;
    }

    return 0;
}

/*
 *      Example client code
 */
int main()
{
    Stack s = {NULL};
    Stack t = {NULL};

    struct my_data aa = {23, "Alice Atkinson"};
    struct my_data bb = {37, "Bob Bates"};
    struct my_data cc = {28, "Carol Clark"};

    stack_push(&s, &aa);
    stack_push(&s, &bb);
    stack_push(&s, &cc);

    stack_write(&s, "kk", my_data_write);

    while (s.head) stack_pop(&s);

    stack_read(&t, "kk", my_data_read);

    while (t.head) {
        struct my_data *p = stack_pop(&t);

        printf("%4d '%s'\n", p->val, p->name);
        free(p);
    }

    return 0;    
}