2016-10-16 5 views
2

Вот моя структура:Fread и FWRITE связанного списка в C

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

мне нужно использовать FWRITE и Fread для хранения значения и загрузить обратно после. Есть ли простой способ?

+1

Читайте о [сериализации] (https://en.wikipedia.org/wiki/Serialization) –

+0

Там нет простого способа до вы пишете функцию, которая это делает. Тогда есть. –

+2

Просто помните, что значение ссылки 'struct Car * next;', записанное в файл, будет устаревшим при перезагрузке данных из файла. Вы будете использовать входные данные для создания нового списка, по элементам, ссылку по ссылке. –

ответ

2

Чтобы написать 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; 
} 

Для чтения записей из файла в 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; 
} 
+0

Если я хочу получить один автомобиль в то время, когда вы читаете и храните переменные temp, тогда вызывайте функцию addToBack, чтобы создать список, вместо этого я могу настроить ваш код, чтобы сделать это? –

+0

@RyanClaxton Я не знаком с 'addToBack()' и не могу ответить на ваш комментарий, но, скорее всего, этот код может быть изменен в соответствии с вашими потребностями. Но если 'addToBack()' это то, что я думаю, это будет способ _bad_ сделать это, если 'addToBack()' должен постоянно переходить LL, чтобы найти его конец. – chux

+0

У меня есть фиктивный узел, который хранит конец списка .. мой компилятор не любит «утверждать» - держись, я думаю, что смогу это сделать. –

0

Следующее было записано мной с манжетой и не было проверено, поэтому может потребоваться настройка. Также обратите внимание; ради времени я не тестировал возвращаемое значение fwrite и fread или проверял наличие ошибок чтения. ВЫ ДОЛЖНЫ СДЕЛАТЬ ЭТО.

Запись файла

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); 

Чтение файла

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); 

Функции
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

'fwrite (bar, ...)' должен быть 'fwrite (foo, ...)' в первом блоке кода. Вы также используете массивы переменной длины (новые в C99). Также представляется неэффективным преобразование в массив только для того, чтобы сделать один вызов fwrite. – dwks

+0

Я согласен с @dwks. Я думаю, было бы более практично делать последовательные 'fwrite', пока вы не попадете в конец связанного списка. В конце концов, OP хочет сделать это со связанными списками, а не с массивом. – Charles

 Смежные вопросы

  • Нет связанных вопросов^_^