Загрузка данных
#include <iostream>
#include <fstream>
#include <string>
#include <limits>
#include <algorithm>
using namespace std;
int readInt(const string& prompt);
class Classroom {
private:
string building; // корпус
int roomNumber; // аудитория
int capacity; // мест
public:
Classroom()
: building(""), roomNumber(0), capacity(0) {
}
Classroom(const string& b, int rn, int cap)
: building(b), roomNumber(rn), capacity(cap) {
}
Classroom(const Classroom& other)
: building(other.building),
roomNumber(other.roomNumber),
capacity(other.capacity) {
}
~Classroom() {}
string getBuilding() const { return building; }
int getRoomNumber() const { return roomNumber; }
int getCapacity() const { return capacity; }
void setBuilding(const string& b) { building = b; }
void setRoomNumber(int rn) { roomNumber = rn; }
void setCapacity(int cap) { capacity = cap; }
void input() {
cout << " Корпус: ";
getline(cin, building);
roomNumber = readInt(" Номер аудитории: ");
capacity = readInt(" Количество мест: ");
}
void print(int idx) const {
cout << idx << ". "
<< "[" << building << "] "
<< "ауд. " << roomNumber
<< ", мест: " << capacity
<< "\n";
}
};
struct Node {
Classroom data;
Node* prev;
Node* next;
Node(const Classroom& c)
: data(c), prev(nullptr), next(nullptr) {
}
};
// двусвязный список
class DoublyLinkedList {
private:
Node* head;
Node* tail;
int size;
public:
DoublyLinkedList() : head(nullptr), tail(nullptr), size(0) {}
~DoublyLinkedList() { clear(); }
// добавить элемент в конец
void pushBack(const Classroom& c) {
Node* newNode = new Node(c);
if (!tail) {
head = tail = newNode;
}
else {
newNode->prev = tail;
tail->next = newNode;
tail = newNode;
}
++size;
}
// удалить элемент по индексу
bool removeAt(int idx) {
Node* cur = getNodeAt(idx);
if (!cur) return false;
if (cur->prev) cur->prev->next = cur->next;
else head = cur->next;
if (cur->next) cur->next->prev = cur->prev;
else tail = cur->prev;
delete cur;
--size;
return true;
}
// получить указатель на узел по индексу
Node* getNodeAt(int idx) const {
if (idx < 1 || idx > size) return nullptr;
Node* cur = head;
for (int i = 1; i < idx; ++i) cur = cur->next;
return cur;
}
int getSize() const { return size; }
bool isEmpty() const { return size == 0; }
Node* getHead() const { return head; }
// очистить список
void clear() {
Node* cur = head;
while (cur) {
Node* next = cur->next;
delete cur;
cur = next;
}
head = tail = nullptr;
size = 0;
}
// вывод списка
void print() const {
if (isEmpty()) {
cout << " Список пуст.\n";
return;
}
cout << "\n --- Список аудиторий ---\n";
Node* cur = head;
int idx = 1;
while (cur) {
cur->data.print(idx);
cur = cur->next;
++idx;
}
}
// запись в файл
void saveToFile(const string& filename) const {
ofstream f(filename);
if (!f) { cout << " Ошибка открытия файла!\n"; return; }
Node* cur = head;
while (cur) {
f << cur->data.getBuilding() << "\n"
<< cur->data.getRoomNumber() << "\n"
<< cur->data.getCapacity() << "\n";
cur = cur->next;
}
cout << " Данные сохранены в файл \"" << filename << "\".\n";
}
// чтение из файла
void loadFromFile(const string& filename) {
ifstream f(filename);
if (!f) { cout << " Файл \"" << filename << "\" не найден!\n"; return; }
clear();
string building;
int roomNumber, capacity;
while (getline(f, building)) {
if (!(f >> roomNumber)) break;
if (!(f >> capacity)) break;
f.ignore();
pushBack(Classroom(building, roomNumber, capacity));
}
cout << " Загружено " << size << " записей из \"" << filename << "\".\n";
}
void sortBy(int field, bool asc) {
if (size < 2) return;
bool swapped;
do {
swapped = false;
Node* cur = head;
while (cur && cur->next) {
bool doSwap = false;
if (field == 0) {
int cmp = cur->data.getBuilding().compare(cur->next->data.getBuilding());
doSwap = asc ? (cmp > 0) : (cmp < 0);
}
else if (field == 1) {
int a = cur->data.getRoomNumber();
int b = cur->next->data.getRoomNumber();
doSwap = asc ? (a > b) : (a < b);
}
else {
int a = cur->data.getCapacity();
int b = cur->next->data.getCapacity();
doSwap = asc ? (a > b) : (a < b);
}
if (doSwap) {
Classroom tmp = cur->data;
cur->data = cur->next->data;
cur->next->data = tmp;
swapped = true;
}
cur = cur->next;
}
} while (swapped);
}
};
void clearInput() {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
int readInt(const string& prompt) {
while (true) {
cout << prompt;
string buf;
char ch;
while ((ch = getchar()) != '\n' && ch != EOF) {
buf += ch;
}
if (buf.empty()) {
cout << " Ошибка: введите число, не пустую строку.\n";
continue;
}
bool valid = true;
for (int i = 0; i < (int)buf.size(); ++i) {
if (i == 0 && buf[i] == '-') {
if (buf.size() == 1) { valid = false; break; }
continue;
}
if (!isdigit((unsigned char)buf[i])) {
valid = false;
break;
}
}
if (!valid) {
cout << " Ошибка: допустимы только цифры\n";
continue;
}
try {
int val = stoi(buf);
return val;
}
catch (...) {
cout << " Ошибка: число слишком большое.\n";
}
}
}
// Меню
void menuAdd(DoublyLinkedList& list) {
cout << "\n === Добавление аудитории ===\n";
Classroom c;
c.input();
list.pushBack(c);
cout << " Запись добавлена.\n";
}
void menuDelete(DoublyLinkedList& list) {
if (list.isEmpty()) { cout << " Список пуст.\n"; return; }
list.print();
int idx = readInt("\n Номер записи для удаления: ");
if (list.removeAt(idx))
cout << " Запись удалена.\n";
else
cout << " Неверный номер записи.\n";
}
void menuEdit(DoublyLinkedList& list) {
if (list.isEmpty()) { cout << " Список пуст.\n"; return; }
list.print();
int idx = readInt("\n Номер записи для редактирования: ");
Node* node = list.getNodeAt(idx);
if (!node) { cout << " Неверный номер записи.\n"; return; }
cout << "\n Что изменить?\n"
<< " 1. Корпус\n"
<< " 2. Номер аудитории\n"
<< " 3. Количество мест\n"
<< " 4. Все поля\n";
int choice = readInt(" Выбор: ");
if (choice == 1 || choice == 4) {
cout << " Новый корпус: ";
string b; getline(cin, b);
node->data.setBuilding(b);
}
if (choice == 2 || choice == 4) {
int rn = readInt(" Новый номер аудитории: ");
node->data.setRoomNumber(rn);
}
if (choice == 3 || choice == 4) {
int cap = readInt(" Новое количество мест: ");
node->data.setCapacity(cap);
}
cout << " Запись обновлена.\n";
}
void menuPrint(DoublyLinkedList& list) {
if (list.isEmpty()) { cout << " Список пуст.\n"; return; }
cout << "\n === Вывод списка ===\n"
<< " Сортировка по:\n"
<< " 1. Корпус\n"
<< " 2. Номер аудитории\n"
<< " 3. Количество мест\n"
<< " 4. Без сортировки\n";
int field = readInt(" Выбор поля: ");
if (field >= 1 && field <= 3) {
cout << " Порядок:\n"
<< " 1. По возрастанию\n"
<< " 2. По убыванию\n";
int order = readInt(" Выбор: ");
bool asc = (order != 2);
list.sortBy(field - 1, asc);
}
list.print();
}
void menuSave(DoublyLinkedList& list) {
cout << " Имя файла: ";
string filename; getline(cin, filename);
list.saveToFile(filename);
}
void menuLoad(DoublyLinkedList& list) {
cout << " Имя файла: ";
string filename; getline(cin, filename);
list.loadFromFile(filename);
}
int main() {
setlocale(LC_ALL, "RU");
DoublyLinkedList list;
cout << "\n|-------------------------------------|\n"
<< "| Учёт аудиторий |\n"
<< "|-------------------------------------|\n";
int choice = 0;
do {
cout << "\n ========================\n"
<< " 1. Добавить аудиторию\n"
<< " 2. Удалить аудиторию\n"
<< " 3. Редактировать аудиторию\n"
<< " 4. Вывести список (с сортировкой)\n"
<< " 5. Сохранить в файл\n"
<< " 6. Загрузить из файла\n"
<< " 0. Выход\n";
choice = readInt(" Выбор: ");
switch (choice) {
case 1: menuAdd(list); break;
case 2: menuDelete(list); break;
case 3: menuEdit(list); break;
case 4: menuPrint(list); break;
case 5: menuSave(list); break;
case 6: menuLoad(list); break;
case 0: break;
default: cout << "\n Неизвестный пункт меню.\n";
}
} while (choice != 0);
return 0;
}