在C中fread和fwrite链表

时间:2022-12-19 07:21:24

Here is my struct:

这是我的结构:

struct Car{
    char plateNum[10];
    char returnDate[7];
    int milage;
    float income;
    struct Car * next;
};
typedef struct Car Car;

I need to use fwrite and fread to store the value and load back in after. Is there an easy way?

我需要使用fwrite和fread来存储值并在之后加载。有一个简单的方法吗?

2 个解决方案

#1


3  

To write a LL to a file

将LL写入文件

// Be sure to have opened the file in binary mode

Car *x = head;

// Walk the list and write each node.
// No need to write the next field - which happens to be the last one.
//                    v-----------------v size of data before the `next` field
while (x && fwrite(x, offsetof(Car, next), 1, out_stream) == 1) {
  x = x->next;
}

To read records from a file into a LL and return the head node:

要将文件中的记录读入LL并返回头节点:

#include <stddef.h>

// Be sure to have opened the file in binary mode
Car *ReadCars(FILE *in_stream) {
  Car Top;
  Top.next = NULL; // code only uses the `next` field of Top

  Car *previous = &Top;
  Car x;

  // While another record was successfully read ...
  while (fread(&x, offsetof(Car, next), 1, in_stream) == 1) {
    // Fill the next field
    x.next = NULL;

    // Allocate space and copy
    previous->next = malloc(sizeof *(previous->next));
    assert(previous->next);
    *(previous->next) = x;

    // Advance to the next
    previous = previous->next;
  }
  return Top.next;
}

#2


0  

The following was written off the cuff by me and has not been tested, so it might need tweaking. Please also note; for the sake of time, I have not tested the return value of fwrite and fread or checked for read errors. YOU SHOULD DO THIS.

以下是由我从袖带上注销的,尚未经过测试,因此可能需要调整。还请注意;为了时间的缘故,我没有测试fwrite和fread的返回值或检查读取错误。你应该做这个。

Writing the file

int length = lengthOfList(bar); // Assuming you've already created bar as a linked list of Cars
Car foo[length];
putLinkedListIntoArray(&bar, foo); 

FILE* fh = NULL;

if((fh = fopen("filename", "wb")) == NULL) {
    // Error and die
}

fwrite(&length, sizeof(int), 1, fh);
fwrite(bar, sizeof(Car), length, fh);
fclose(fh);

Reading the file

FILE* fh = NULL;

if((fh = fopen("filename", "rb")) == NULL) {
    // Error and die
}

int length;

fread(&length, sizeof(int), 1, fh);

Car foo[length];
fread(foo, sizeof(Car), length, fh);
fclose(fh);
relinkCarList(foo, length);

Functions

int lengthOfList(Car* start) {
   int length;
   for(length = 0; start->next != NULL; length++) {
       start = start->next;
   }
   return length;
}

void putLinkedListIntoArray(Car* start, Car* array) {
   for(int i = 0; start->next != NULL; i++) {
       array[i] = *start;
       start = start->next;
   }
}

void relinkCarList(Car* array, int length) {
   for(int i = 0; i < length; i++) {
       if(i < length - 1) {
           array[i].next = array[i + 1].next;
       }
   }
}

#1


3  

To write a LL to a file

将LL写入文件

// Be sure to have opened the file in binary mode

Car *x = head;

// Walk the list and write each node.
// No need to write the next field - which happens to be the last one.
//                    v-----------------v size of data before the `next` field
while (x && fwrite(x, offsetof(Car, next), 1, out_stream) == 1) {
  x = x->next;
}

To read records from a file into a LL and return the head node:

要将文件中的记录读入LL并返回头节点:

#include <stddef.h>

// Be sure to have opened the file in binary mode
Car *ReadCars(FILE *in_stream) {
  Car Top;
  Top.next = NULL; // code only uses the `next` field of Top

  Car *previous = &Top;
  Car x;

  // While another record was successfully read ...
  while (fread(&x, offsetof(Car, next), 1, in_stream) == 1) {
    // Fill the next field
    x.next = NULL;

    // Allocate space and copy
    previous->next = malloc(sizeof *(previous->next));
    assert(previous->next);
    *(previous->next) = x;

    // Advance to the next
    previous = previous->next;
  }
  return Top.next;
}

#2


0  

The following was written off the cuff by me and has not been tested, so it might need tweaking. Please also note; for the sake of time, I have not tested the return value of fwrite and fread or checked for read errors. YOU SHOULD DO THIS.

以下是由我从袖带上注销的,尚未经过测试,因此可能需要调整。还请注意;为了时间的缘故,我没有测试fwrite和fread的返回值或检查读取错误。你应该做这个。

Writing the file

int length = lengthOfList(bar); // Assuming you've already created bar as a linked list of Cars
Car foo[length];
putLinkedListIntoArray(&bar, foo); 

FILE* fh = NULL;

if((fh = fopen("filename", "wb")) == NULL) {
    // Error and die
}

fwrite(&length, sizeof(int), 1, fh);
fwrite(bar, sizeof(Car), length, fh);
fclose(fh);

Reading the file

FILE* fh = NULL;

if((fh = fopen("filename", "rb")) == NULL) {
    // Error and die
}

int length;

fread(&length, sizeof(int), 1, fh);

Car foo[length];
fread(foo, sizeof(Car), length, fh);
fclose(fh);
relinkCarList(foo, length);

Functions

int lengthOfList(Car* start) {
   int length;
   for(length = 0; start->next != NULL; length++) {
       start = start->next;
   }
   return length;
}

void putLinkedListIntoArray(Car* start, Car* array) {
   for(int i = 0; start->next != NULL; i++) {
       array[i] = *start;
       start = start->next;
   }
}

void relinkCarList(Car* array, int length) {
   for(int i = 0; i < length; i++) {
       if(i < length - 1) {
           array[i].next = array[i + 1].next;
       }
   }
}