13
Окт
2021

Как прочитать бинарный файл в двусвязный список?

Есть структура и класс:

struct listik {
    listik* prev;
    listik* next;
    std::string data;
};

class ListWork {
public:
    ~List();
    void read(FILE* file);
    void write(FILE* file);

    void Append(std::string data);

private:
    listik* head;
    listik* tail;
};

Записываю в файл так:

void ListWork::write(FILE* file)//save to file serialized 
{
    Append("I ");
    Append("Wanna ");
    Append("Sleep! ");

    const char* path = "path//myfile.bin";

    if ((file = fopen(path, "wb")))
    {
        while (head != nullptr)
        {
            if (fwrite(&head->data, sizeof(head->data), 1, file))
                head = head->next;
        }
        std::cout << "File was successfully serialized!" << std::endl;
        fclose(file);
    }
}

И пытаюсь читать так:

void ListWork::read(FILE* file)//get from file deserialized
{
    //cleaning up the list
    listik *freeMe = head;
    listik *holdMe = nullptr;
    while (freeMe != nullptr)
    {
        holdMe = freeMe->next;
        std::cout << "Free list";
        free(freeMe);
        freeMe = holdMe;
    }
    count = 0;

    //deserialize

    const char* path = "path//flower.bin";

    listik *node;
    if ((file = fopen(path, "rb")))
    {
        node = (listik *)malloc(sizeof(listik));
        //node->next = nullptr;
        while (!feof(file))
        {
            fread(&node, sizeof(listik), 1, file);
            if (head != nullptr)
            {
                std::cout << "list is not empty\n";
                node->prev = tail; //***здесь ошибка:***Exception thrown: write access violation. node was nullptr.
                tail->next = node;
                tail = node;
            }
            else
            {
                std::cout << "list is empty\n";
                node->prev = tail;
                head = tail = node;
            }

            //std::cout << node->data;
        }
    }
    else {
        printf("FILE OPEN ERROR FOR READ\n");
    }
    fclose(file);
}

Не очень понимаю, что делаю не так. Если использую ту же структуру перемещения по списку при добавлении через функцию, то таких проблем нет.

Функция добавления:

void ListWork::Append(std::string data)
{
    listik* el = new listik();
    el->data = data;

    el->next = nullptr;
    if (head != nullptr)
    {
        el->prev = tail;
        tail->next = el;
        tail = el;
    }
    else
    {
        el->prev = nullptr;
        head = tail = el;
    }
}

Источник: https://ru.stackoverflow.com/questions/1338066/%D0%9A%D0%B0%D0%BA-%D0%BF%D1%80%D0%BE%D1%87%D0%B8%D1%82%D0%B0%D1%82%D1%8C-%D0%B1%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D1%8B%D0%B9-%D1%84%D0%B0%D0%B9%D0%BB-%D0%B2-%D0%B4%D0%B2%D1%83%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D1%8B%D0%B9-%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA

13
Окт
2021

Как прочитать бинарный файл в двусвязный список?

Есть структура и класс:

struct listik {
    listik* prev;
    listik* next;
    std::string data;
};

class ListWork {
public:
    ~List();
    void read(FILE* file);
    void write(FILE* file);

    void Append(std::string data);

private:
    listik* head;
    listik* tail;
};

Записываю в файл так:

void ListWork::write(FILE* file)//save to file serialized 
{
    Append("I ");
    Append("Wanna ");
    Append("Sleep! ");

    const char* path = "path//myfile.bin";

    if ((file = fopen(path, "wb")))
    {
        while (head != nullptr)
        {
            if (fwrite(&head->data, sizeof(head->data), 1, file))
                head = head->next;
        }
        std::cout << "File was successfully serialized!" << std::endl;
        fclose(file);
    }
}

И пытаюсь читать так:

void ListWork::read(FILE* file)//get from file deserialized
{
    //cleaning up the list
    listik *freeMe = head;
    listik *holdMe = nullptr;
    while (freeMe != nullptr)
    {
        holdMe = freeMe->next;
        std::cout << "Free list";
        free(freeMe);
        freeMe = holdMe;
    }
    count = 0;

    //deserialize

    const char* path = "path//flower.bin";

    listik *node;
    if ((file = fopen(path, "rb")))
    {
        node = (listik *)malloc(sizeof(listik));
        //node->next = nullptr;
        while (!feof(file))
        {
            fread(&node, sizeof(listik), 1, file);
            if (head != nullptr)
            {
                std::cout << "list is not empty\n";
                node->prev = tail; //***здесь ошибка:***Exception thrown: write access violation. node was nullptr.
                tail->next = node;
                tail = node;
            }
            else
            {
                std::cout << "list is empty\n";
                node->prev = tail;
                head = tail = node;
            }

            //std::cout << node->data;
        }
    }
    else {
        printf("FILE OPEN ERROR FOR READ\n");
    }
    fclose(file);
}

Не очень понимаю, что делаю не так. Если использую ту же структуру перемещения по списку при добавлении через функцию, то таких проблем нет.

Функция добавления:

void ListWork::Append(std::string data)
{
    listik* el = new listik();
    el->data = data;

    el->next = nullptr;
    if (head != nullptr)
    {
        el->prev = tail;
        tail->next = el;
        tail = el;
    }
    else
    {
        el->prev = nullptr;
        head = tail = el;
    }
}

Источник: https://ru.stackoverflow.com/questions/1338066/%D0%9A%D0%B0%D0%BA-%D0%BF%D1%80%D0%BE%D1%87%D0%B8%D1%82%D0%B0%D1%82%D1%8C-%D0%B1%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D1%8B%D0%B9-%D1%84%D0%B0%D0%B9%D0%BB-%D0%B2-%D0%B4%D0%B2%D1%83%D1%81%D0%B2%D1%8F%D0%B7%D0%BD%D1%8B%D0%B9-%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA

Тебе может это понравится...

Добавить комментарий