Двухсвязный список
beq
c_cpp
3 years ago
18 kB
8
Indexable
#include <iostream>
#include <iomanip>
#include <string>
#include "Windows.h"
#include <fstream>
#include <conio.h>
using namespace std;
struct bibliya
{
string fio;
string name_knig;
string godizd;
string ins;
int exemp;
bibliya* next = nullptr;
bibliya* prev = nullptr;
};
//Добавление в список
void add(bibliya** q)
{
system("cls");
bibliya* current = *q; //Указатель на текущий элемент
string str;
int temp;
cout << "Каким образом внести новые данные? " << endl;
cout << "1. В ручную" << endl;
cout << "2. Загрузить список из файла" << endl;
cout << "3. Главное меню" << endl;
char select = '-';
select = _getch();
switch (select)
{
case '1':
{
system("cls");
bibliya* new_product;
new_product = new bibliya;
cout << "Введите фамилию: ";
cin >> str;
new_product->fio = str;
str = "";
cout << "Введите инициалы: ";
cin >> str;
new_product->ins = str;
getline(cin, str);
cout << "\nВведите название книги: ";
getline(cin, str);
new_product->name_knig = str;
str = "";
cout << "\nУкажите год издания: ";
cin >> str;
new_product->godizd = str;
str = "";
cout << "\nКоличество экземпляров: ";
cin >> temp;
new_product->exemp = temp;
if (!(*q))
{
*q = new_product;
(*q)->next = nullptr;
(*q)->prev = nullptr;
}
else
{
bibliya* current = (*q)->next;
bibliya* previous = *q;
while (current)
{
previous = current;
current = current->next;
}
previous->next = new_product;
new_product->prev = previous;
new_product->next = current;
}
break;
}
case '2': //ЗАГРУЗКА из правильно заполненного файла
{
system("cls");
char FILE[256];
cout << "Укажите путь к файлу (по умолчанию text.txt):";
cin.getline(FILE, 256);
if (strcmp(FILE, "") == 0) {
strcpy_s(FILE, "text.txt");
}
ifstream fin;
fin.open(FILE, fstream::in);
if (fin.is_open())
{
string lineName;
string lineins;
string lineshop_name;
string lineProdNumber;
string lineProdPrice;
int int_line = 0;
int unsigned counter = 0;
while (!fin.eof())
{
counter++;
if (counter == 1)//фамилия
{
getline(fin, lineName);
}
else if (counter == 2) //инициалы
{
getline(fin, lineins);
}
else if (counter == 3)//Название книги
{
getline(fin, lineshop_name);
}
else if (counter == 4)//год издания
{
getline(fin, lineProdNumber);
}
else if (counter == 5)//экзмепляры
{
getline(fin, lineProdPrice);
}
else
{
if (lineName.length() == 0 || lineins.length() == 0 || lineshop_name.length() == 0 || lineProdNumber.length() == 0 || lineProdPrice.length() == 0) { cout << "Ошибка чтения файла. Файл пуст или неправильно заполнен!" << endl; break; }
counter = 0;
bibliya* new_node;
new_node = new bibliya;
if (!(*q))
{
*q = new_node;
(*q)->next = nullptr;
(*q)->prev = nullptr;
}
else {
bibliya* current = (*q)->next;
bibliya* previous = *q;
while (current) {
previous = current;
current = current->next;
}
previous->next = new_node;
new_node->prev = previous;
new_node->next = current;
}
new_node->fio = lineName;
new_node->ins = lineins;
new_node->name_knig = lineshop_name;
new_node->godizd = lineProdNumber;
new_node->exemp = stoi(lineProdPrice);
lineName = lineins = lineshop_name = lineProdNumber = lineProdPrice = "";
}
}
fin.close();
}
else
{
cout << "Не удалось открыть файл" << endl;
}
break;
}
default:
{
system("cls");
cout << "\n\nДобавление отменено! Возврат в главное меню.\n\nНажмите любую кнопку чтобы вернуться.";
system("pause");
break;
}
}
}
//Вывод на экран
void output(bibliya** q, int a)
{
int i = 1;
bibliya* current = *q;
int flag = 1;
if (a == 1) //если выбрано с начала алфавита
{
cout << "Весь список книг отсортированный по алфавиту\n";
while (current)
{
cout << " ФИО: " << current->fio << " " << current->ins << endl;
cout << " Название книги: " << current->name_knig << endl;
cout << " Год издания: " << current->godizd << endl;
cout << " Количество экземпляров: " << current->exemp << endl;
current = current->next;
i++;
cout << "\n";
}
cout << "\nЗаписать всё в файл? y/n ";
char yesno;
yesno = _getch();
if (yesno == 'y')
{
bibliya* sacc = *q;
fstream fout;
fout.open("rez.txt", ifstream::app); //название файла в который запись пойдет
if (fout.is_open())
{
while (sacc)
{
string txt = sacc->fio + '\n' + sacc->ins + '\n' + sacc->name_knig + '\n' + sacc->godizd + '\n' + to_string(sacc->exemp) + '\n';
fout << txt;
sacc = sacc->next;
}
cout << "\nЗапись произошла успешно!\n";
}
else
{
cout << "\nНет доступа к файлу. Запись прервана!" << endl;
}
}
}
else //если выбрано с конца алфавита
{
while (current->next)
{
current = current->next;
}
cout << "Весь список книг отсортированный с конца алфавита\n";
while (current)
{
cout << " ФИО: " << current->fio << " " << current->ins << endl;
cout << " Название книги: " << current->name_knig << endl;
cout << " Год издания: " << current->godizd << endl;
cout << " Количество экземпляров: " << current->exemp << endl;
current = current->prev;
i++;
cout << "\n";
}
}
}
void del(bibliya*& q)
{
string candidat;
bibliya* current = q;
getline(cin, candidat);
cout << "Укажите название книги, сведения о которой хотите стереть: ";
getline(cin, candidat);
cout << endl;
while (current != nullptr)
{
if (current->name_knig == candidat)
{
cout << " ФИО: " << current->fio << " " << current->ins << endl;
cout << " Название книги: " << current->name_knig << endl;
cout << " Год издания: " << current->godizd << endl;
cout << " Количество экземпляров: " << current->exemp << endl;
char answer = 'n';
cout << "\nУдалить сведения об этой книге? y/n ? ";
cin >> answer;
if (answer == 'y' || answer == 'Y')
{
if (current->prev == nullptr && current->next != nullptr) //Если нет родителя, но есть потомок
{
current = current->next;
q = current;
}
else if (current->prev != nullptr && current->next == nullptr)//Если есть родитель, но нет потомков
{
current->prev->next = nullptr;
}
else if (current->prev == nullptr && current->next == nullptr)//Нет ни родителя, ни потомка
{
current = nullptr;
}
else if (current->prev != nullptr && current->next != nullptr)//Есть и родитель, и потомок
{
current->fio = current->next->fio;
current->ins = current->next->ins;
current->name_knig = current->next->name_knig;
current->godizd = current->next->godizd;
current->exemp = current->next->exemp;
current->prev->next = current->next;
current->next->prev = current->prev;
}
cout << "\nСведения о книге были уcпешно удалены!" << endl;
}
else
{
cout << "Вы выбрали отмену удаления, данные были сохранены!" << endl;
}
}
if (current != nullptr)current = current->next;
}
}
void sort(bibliya*& Head) //Сортировка пузырьком
{
bibliya* left = Head; //Первый элемент — это пусть будет голова
bibliya* right = Head->next; //Второй элемент — это пусть будет следующий за головой элемент
bibliya* temp = new bibliya; //Временное звено для хранения переставляемого всех значений переставляемого звена
while (left->next) //Обходим по всем звеньям, за исключением крайнего правого
{
while (right) //Обходим по всем звеньям, включая крайний правый (по всем относительно первого левого на текущий момент)
{
if ((left->fio) > (right->fio)) //Проверяем необходимость перестановки
{
temp->name_knig = left->name_knig;
left->name_knig = right->name_knig;
right->name_knig = temp->name_knig;
temp->fio = left->fio;
left->fio = right->fio;
right->fio = temp->fio;
temp->ins = left->ins;
left->ins = right->ins;
right->ins = temp->ins;
temp->godizd = left->godizd;
left->godizd = right->godizd;
right->godizd = temp->godizd;
temp->exemp = left->exemp;
left->exemp = right->exemp;
right->exemp = temp->exemp;
}
right = right->next; //не забываем направлять указатель на следующий элемент (по подобию инкремента), иначе цикл зависнет
}
left = left->next; //не забываем направлять указатель на следующий элемент (по подобию инкремента), иначе цикл зависнет
right = left->next; //Поскольку второй указатель убежал немного вперёд, обязательно возвращаем его назад, это следующий элемент относительно текущего первого
}
}
//Поиск
void TryToFind(bibliya** q)
{
int flag = false;
string knig1;
bibliya* current = *q;
bibliya* previous = nullptr;
getline(cin, knig1);
cout << "Укажите название книги: ";
getline(cin, knig1);
while (current != nullptr)
{
if (current->name_knig == knig1)
{
cout << " ФИО: " << current->fio << " " << current->ins << endl;
cout << " Название книги: " << current->name_knig << endl;
cout << " Год издания: " << current->godizd << endl;
cout << " Количество экземпляров: " << current->exemp << endl;
cout << "\n";
flag = true;
}
previous = current;
current = current->next;
}
if (flag == false)
{
cout << "\nНе найдено книг с данным условием!";
}
}
void help()
{
system("cls");
cout << "Вариант 16" << endl;
cout << "1. Составить программу, которая содержит текущую информацию о книгах в библиотеке." << endl;
cout << "Сведения о книгах включают:" << endl;
cout << "• фамилию и инициалы автора;" << endl;
cout << "• название;" << endl;
cout << "• год издания;" << endl;
cout << "• количество экземпляров данной книги в библиотеке;\n" << endl;
cout << "2. Программа должна обеспечивать:\n" << endl;
cout << "• хранение всех данных обо всех книгах в библиотеке в виде односвязного списка (очередь);" << endl;
cout << "• добавление данных о книгах вновь поступивших в библиотеку;" << endl;
cout << "• удаление данных о списываемой книге, название которой введено с клавиатуры;" << endl;
cout << "• вывод информации обо всех книгах в библиотеке;" << endl;
cout << "• по запросу выводится информация о книге, название которой введено с клавиатуры." << endl;
cout << "3.Программа должна обеспечивать диалог с помощью меню." << endl;
system("pause");
}
void info()
{
system("cls");
cout << "Динамические структуры данных" << endl;
cout << "(Очереди)" << endl;
cout << "Версия 2.0" << endl;
cout << "Год 2022" << endl;
cout << "Разработчик ---" << endl;
cout << "Студент группы ---" << endl;
system("pause");
}
void take_out(bibliya** q)
{
bibliya* old_header = *q;
while (*q)
{
(*q) = (*q)->next;
free(old_header);
old_header = *q;
}
}
int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
bool flag = false;
bool flag1 = false;
bool flag2 = false;
bibliya* q = nullptr;
int vibor;
int choice;
do {
system("cls");
cout << "1. Добавить книгу.\n";
cout << "2. Удалить книгу.\n";
cout << "3. Показать полный список библиотеки.\n";
cout << "4. Поиск книги по названию.\n";
cout << "5. О программе.\n";
cout << "6. Помощь.\n";
cout << "7. Выход\n";
do
{
cout << "\nВведите номер пункта меню: ";
cin >> vibor;
if (vibor < 1 || vibor > 8)
{
cout << "Введено неверное значение. Повторите ввод: ";
cin.clear();
cin.sync();
}
} while (vibor < 1 || vibor > 8);
system("cls");
switch (vibor)
{
case 1: {
do
{
cin.ignore();
add(&q);
flag = true;
cout << "\nЕсли хотите ещё добавить книги введите 1, иначе 2\n";
do
{
cin >> choice;
if (choice < 1 || choice > 2)
{
cout << "Введено неверное значение. Повторите ввод: ";
cin.clear();
cin.sync();
}
} while (choice < 1 || choice > 2);
} while (choice == 1);
cout << "Чтобы вернуться в меню, нажмите любую клавишу" << endl;
_getch();
break;
}
case 2:
{
if (q)
{
do
{
del(q);
cout << "\nЕсли хотите продолжить введите 1, иначе 2" << endl;
do
{
cin >> choice;
if (choice < 1 || choice > 2)
{
cout << "Введено неверное значение. Повторите ввод: ";
cin.clear();
cin.sync();
}
} while (choice < 1 || choice > 2);
cout << "\n";
} while (choice == 1);
}
else
{
cout << "\nИнформационная система пуста!\n";
}
cout << "Чтобы вернуться в меню, нажмите любую клавишу" << endl;
_getch();
break;
}
case 3:
{
if (q)
{
sort(q);
do
{
system("cls");
cout << "1. Вывести библиографический список с начала алфавита.\n";
cout << "2. Вывести библиографический список с конца алфавита.\n";
cout << "3. Вернуться в главное меню.\n";
do
{
cin >> choice;
if (choice < 1 || choice > 3)
{
cout << "\nВведено неверное значение. Повторите ввод: ";
cin.clear();
cin.sync();
}
} while (choice < 1 || choice > 3);
system("cls");
switch (choice)
{
case 1:
{
output(&q, 1);
cout << "\nЧтобы продолжить, нажмите любую клавишу" << endl;
_getch();
break;
}
case 2:
{
output(&q, 2);
cout << "\nЧтобы продолжить, нажмите любую клавишу" << endl;
_getch();
break;
}
}
} while (choice != 3);
}
else
{
cout << "\nИнформационная система пуста.\n";
cout << "\nДля продолжения нажмите любую клавишу..." << endl;
_getch();
}
break;
}
case 4:
{
if (q)
{
do
{
TryToFind(&q);
cout << "\nЕсли хотите продолжить введите 1, иначе 2" << endl;
do
{
cin >> choice;
if (choice < 1 || choice > 2)
{
cout << "\nВведено неверное значение. Повторите ввод: ";
cin.clear();
cin.sync();
}
} while (choice < 1 || choice > 2);
} while (choice == 1);
}
else
{
cout << "\nСписок библиотеки пуст.\n";
}
break;
}
case 5:
{
info();
break;
}
case 6:
{
help();
break;
}
case 7:
{
take_out(&q);
break;
}
}
} while (vibor != 7);
return 0;
}
Editor is loading...