Организация и практическое применение двусвязных линейных списков. Вариант № 5, страница 4

Функция сохранения в файл (save) организована следующим образом. После вызова функции из главного меню происходит стандартная проверка наличия активного списка, если список существует, функция продолжает работу.

Сначала в каталоге, из которого была запущена программа, создается и открывается для записи в бинарном режиме файл data.txt. Запись в файл реализована при помощи цикла WHILE, который выполняется до тех пор, пока не будет достигнут конец списка NULL.

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

После завершения процедуры записи списка, файл закрывается и на экран под пунктами меню выводится сообщение об успешном завершении процедуры записи  в файл.

Исходный код функции.

void save(item *p)

{FILE *in;

  if (tail == NULL)

  {

    printf("\n  Список товаров отсутствует нажмите <1>\n       чтобы создать новый список,\n     либо загрузите список из файла");

    getch();

  }

  else {

    in = fopen("data.txt", "wb");

    if (in != NULL)

    {

      while (p != NULL)

      {

        if (!fwrite(p, sizeof(item), 1, in))

        {

          perror("fwrite");

          getchar();

          fclose(in);

          return ;

        }

        p = p->next;

      }

      fclose(in);

      printf("\n Список успешно сохранен в файл!");

      getch();

    }

    else

    {

      printf("Ошибка! Не удалось создать/прочитать файл\n");

      printf("Нажмите любую клавишу...\n");

      getchar();

      return 0;

    }

  }

}

//Заголовок функции

//Инициализация переменных

//Проверка на наличие активного списка

//Вывод сообщения об отсутствии списка

//Переход к выполнению операции сохранения списка

//Создание файла data.txt и открытие для записи

//Цикл повторения записи до конца списка

//Если в запись невозможна

//Детектор ошибок

//Закрытие файла

//Продвижение по списку

//Закрытие файла

//Сообщение о завершении операции сохранения

//Сообщение об ошибке

Функция загрузки списка из файла (load) позволяет загрузить ранее сохраненный список из файла. Функция доступна сразу после запуска программы, как один из вариантов создания списка.

После запуска функции происходит очищение памяти под новый список, без которого процесс загрузки проходил бы некорректно. Очищение памяти основано на цикле WHILE, который выполняется до тех пор, пока не будет достигнут конец существующего списка NULL, если таковой имеется.

Затем программа ищет в каталоге, из которого она была запущена файл data.txt после чего открывает его в режиме чтения.

Формирование списка из прочитанных данных основано на цикле WHILE, который выполняется до тех пор, пока не будет достигнут конец файла.

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

Считанной из файла структуре назначаются новые, валидные указатели, после чего цикл повторяется.

По завершению формирования списка выводится сообщение об успешной загрузке из файла.

Исходный код функции.

void load(void)

{

  item *p,  *pr;

  FILE *in;

  pr = NULL;

  p = head;

  while (p != NULL)

  {

    item *pTemp;

    pTemp = p->next;

    free(p);

    p = pTemp;

  }

  in = fopen("data.txt", "rb");

  do

  {

    p = (item*)malloc(sizeof(item));

    fread(p, sizeof(item), 1, in);

    p->prev = NULL;

    p->next = NULL;

    p->prev = pr;

    if (pr != NULL)

      pr->next = p;

    else

      head = p;

    pr = p;

  }

  while (!feof(in));

  tail = p->prev;

  tail->next = NULL;

  p = tail;

  printf("\n Список успешно загружен из файла!");

  getch();

}

//Заголовок функции

//Инициализация переменных и указателей

//Обнуление указателей

//Процедура очистки памяти

//Открытие файла data.txt в режиме чтения

//Выделение памяти под новую структуру

//Чтение из файла одной структуры item

//Обнуление невалидных указателей

//Назначение новых указателей

//Выполнение цикла до тех пор пока не будет достигнут конец файла

//Вывод сообщения об окончании процедуры загрузки из файла.

Функции завершения работы программы как таковой не существует. Завершение программы доступно из главного меню программы.

По нажатию клавиши <0> происходит возвращение нулевого значения return 0 и программа завершает свою работу. Существующий список не сохраняется автоматически потому, в случае необходимости восстановления данных пользователь должен предварительно сохранить созданный либо измененный список.

ЗАКЛЮЧЕНИЕ

На примере программы «Наш склад» мы постарались реализовать некоторые приемы работы с двусвязными списками, применив двусвязный список в качестве метода хранения информации состоящей из структур.

Мы пришли к выводу, что двусвязный список, несмотря на простоту организации, предоставляет достаточно широкий диапазон возможностей его модификации.

Свойства линейных списков при двусвязном хранении делают возможным выполнение таких операций как поиск, сортировка, добавление новой записи в любую позицию списка и её удаление. Структура записи может включать в себя произвольное количество разнотипных элементов, что делает возможным использование двусвязного списка в качестве подобия базы данных.