#include "pch.h" #include #include #include //файлы #include //файлы #include //преобразование типов в другие #include //форматирование вывода using namespace std; struct train { string destination;//строка из букв, пробелов, тире и цифр int number;//целое число unsigned int departureTime;//целое число минут }; struct list_node { train* data; list_node* next; }; void printTrain(train* t) { int k = 9 - to_string(t->number).length(); cout << t->number << setw (k + 17) << t->departureTime/60 << ":"; if (t->departureTime % 60 > 9) { cout << t->departureTime % 60 << setw(43); } else { cout << "0" << t->departureTime % 60 << setw(43); } cout << t->destination << endl; cout << endl; } bool charIsDigit(char c) { return c >= '0' && c <= '9'; } bool stringIsNumber(string s) { for (char c : s) { if (!charIsDigit(c)) { return false; } } return true; } class TrainList { list_node *head; public: TrainList() { head = NULL; } ~TrainList(); bool trainWithNumberExists(int number); void add(); void remove(); void doRemove(int trainNumber); void show(); void afterTime(); void sort(); void save(); void load(); void modify(); void freeList(); void exiting(); }; TrainList::~TrainList(void) { while (head != NULL) { list_node *tmp = head->next; delete head; head = tmp; } } bool TrainList::trainWithNumberExists(int number) { list_node *iter = head; while (iter != NULL) { if (iter->data->number == number) { return true; } iter = iter->next; } return false; } void TrainList::show() { if (head == NULL) { cerr << "!Empty list!" << endl; return; } cout << "Train number Train departureTime Train destination" << endl; //заголовок таблици list_node *iter = head; while (iter != NULL) { printTrain(iter->data); iter = iter->next; } } int readTime() { string departureTimeString; int hour = 0; int minut = 0; getline(cin, departureTimeString); int r = sscanf_s(departureTimeString.c_str(), "%d %d", &hour, &minut); if (r != 2 || hour < 0 || hour > 23 || minut < 0 || minut > 59) { cerr << "!Wrong time format (H M)!" << endl; return -1; } return hour * 60 + minut; } void TrainList::add() { int trainNumber; int departTime; while (true) { cout << "Enter number of a train you want to add (only digits and leangth <= 9): " << endl; string trainNumberString; getline(cin, trainNumberString); if(trainNumberString.length() > 9) { cerr << "!Incorrect train number!" << endl; continue; } if (!stringIsNumber(trainNumberString)) { cerr << "!Incorrect train number!" << endl; continue; } trainNumber = stoi(trainNumberString); if (trainWithNumberExists(trainNumber)) { cerr << "!Train with such number already exists!" << endl; continue; } break; } while (true) { cout << "Enter departure time of a train you want to add (H M): " << endl; departTime = readTime(); if (departTime == -1) { continue; } break; } cout << "Enter destination of a train you want to add" << endl; //нижний string destination; getline(cin, destination); train* newTrain = new train; newTrain->number = trainNumber; newTrain->departureTime = departTime; newTrain->destination = destination; list_node* newNode = new list_node; newNode->data = newTrain; newNode->next = head; head = newNode; cout << "Element was added!" << endl; } void TrainList::doRemove(int trainNumber) { list_node *iter = head; list_node *prev = NULL; while (iter != NULL) { if (iter->data->number == trainNumber) { if (iter == head) { head = iter->next; delete head; } else { prev->next = iter->next; delete iter; iter = prev; } } prev = iter; iter = iter->next; } } void TrainList::remove() { if (head == NULL) { cerr << "!Empty list!" << endl; return; } string trainNumberString; int trainNumber; while (true) { cout << "Enter number of train you want to delete" << endl; getline(cin, trainNumberString); if (!stringIsNumber(trainNumberString)) { cerr << "!Incorrect train number!" << endl; continue; } trainNumber = stoi(trainNumberString); if (!trainWithNumberExists(trainNumber)) { cerr << "!There is no train with such number!" << endl; continue; } break; } doRemove(trainNumber); cout << "Train was removed!" << endl; } void TrainList::afterTime() { if (head == NULL) { cerr << "!Empty list!" << endl; return; } int willDeparture; while (true) { cout << "After what time do you need trains (H M): " << endl; willDeparture = readTime(); if (willDeparture == -1) { continue; } break; } list_node *iter = head; bool flag = false; while (iter != NULL) { if (iter->data->departureTime >= willDeparture) { printTrain(iter->data); flag = true; } iter = iter->next; } if (!flag) { cerr << "!No trains after that time!" << endl; } } void TrainList::load() { ifstream fp("trains.txt"); freeList(); //При загрузке очищает память int trainNumber = 0; int departureTime = 0; char destination[100]; string line; size_t line_size; int r; int notLoaded = 0; char trainNumberString[100]; char departureTimeString[100]; while (getline(fp, line)) { r = sscanf_s(line.c_str(), "%s %s %[^\n\t]", trainNumberString, (rsize_t)sizeof trainNumberString, departureTimeString, (rsize_t)sizeof departureTimeString, destination, (rsize_t)sizeof destination); if (r == 3 && stringIsNumber(trainNumberString)) { trainNumber = stoi(trainNumberString); if (!trainWithNumberExists(trainNumber) && stringIsNumber(departureTimeString)) { departureTime = stoi(departureTimeString); if (departureTime < 1440) { train* newTrain = new train; newTrain->number = trainNumber; newTrain->departureTime = departureTime; newTrain->destination = (destination); list_node* newNode = new list_node; newNode->data = newTrain; newNode->next = head; head = newNode; } else { notLoaded++; } } else { notLoaded++; } } else { notLoaded++; } } if (notLoaded > 0) { cout << notLoaded << " trains wasnt loaded" << endl; cout << "File was loaded but not fully!" << endl; fp.close(); return; } cout << "File was loaded fully!" << endl; fp.close(); } void TrainList::save() { if (head == NULL) { cerr << "!Empty list!" << endl; return; } ofstream file; file.open("trains.txt", ofstream::out | ofstream::trunc); list_node *iter = head; while (iter != NULL) { file << iter->data->number << " " << iter->data->departureTime << " " << iter->data->destination << endl; iter = iter->next; } file.close(); cout << "Data was saved!" << endl; } void TrainList::modify() { if (head == NULL) { cerr << "!Empty list!" << endl; return; } string modiTrainString; int modiTrain; int departTime; while (true) { cout << "Which train to modify: "; getline(cin, modiTrainString); if (!stringIsNumber(modiTrainString)) { cerr << "!Incorrect train number!" << endl; continue; } modiTrain = stoi(modiTrainString); if (!trainWithNumberExists(modiTrain)) { cerr << "!There is no train with such number!" << endl; continue; } break; } while (true) { cout << "Enter new departure time of a train (H M): " << endl; departTime = readTime(); if (departTime == -1) { continue; } break; } cout << "Enter new destination of a train: " << endl; string destination; getline(cin, destination); list_node *iter = head; while (iter != NULL) { if (iter->data->number == modiTrain) { iter->data->departureTime = departTime; iter->data->destination = destination; } iter = iter->next; } cout << "Modifying completed!" << endl; return; } void TrainList::sort() { if (head == NULL) { cerr << "!Empty list!" << endl; return; } list_node *iter = head; bool bubble = true; while (bubble) { bubble = false; list_node *prev = NULL; iter = head; while (iter != NULL) { list_node *next = iter->next; if (next != NULL && iter->data->departureTime > next->data->departureTime) { if (prev) { prev->next = next; } else { head = next; } list_node* tmp = next->next; next->next = iter; iter->next = tmp; bubble = true; } prev = iter; iter = next; } } cout << "List was sorted!" << endl; } void TrainList::freeList() { list_node *iter = head; while (iter != NULL) { list_node* nIter = iter->next; free(iter->data); free(iter); iter = nIter; } head = NULL; } void TrainList::exiting() { cout << "Do you want to save data? (y-YES/n-NO): " << endl; char ans; cin >> ans; cin.ignore(); if (ans == 'y') { save(); freeList(); exit(0); } if (ans == 'n') { freeList(); exit(0); } cerr << "!Wrond command, try again!" << endl; } int main() { setlocale(LC_ALL, "ru"); TrainList trains; while (true) { cout << "Commands:" << endl; cout << "Enter 1 to add new train;" << endl; cout << "Enter 2 to modify one of the trains" << endl; cout << "Enter 3 to show existing trains" << endl; cout << "Enter 4 to show trains that departures afther certain time" << endl; cout << "Enter 5 to delete one of the trains" << endl; cout << "Enter 6 to save trains to file" << endl; cout << "Enter 7 to load trains from file (existing data will be deleted)" << endl; cout << "Enter 8 to sort trains by time" << endl; cout << "Enter 9 to exit" << endl; string command; getline(cin, command); if (command.size() > 1) { cerr << "!Wrond command, try again!" << endl; continue; } if (command.size() == 0){ cout << endl; continue; } switch (command[0]) { case '1': trains.add(); break; case '2': trains.modify(); break; case '3': trains.show(); break; case '4': trains.afterTime(); break; case '5': trains.remove(); break; case '6': trains.save(); break; case '7': trains.load(); break; case '8': trains.sort(); break; case '9': trains.exiting(); break; default: cerr << "!Wrond command, try again!" << endl; continue; } } return 0; }