Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <string>
- #include "windows.h"
- using namespace std;
- int sizeofFile(ifstream * file); // Подсчитывает количесво строк в файле
- struct STUDENT
- {
- string name; // Фамилия
- int yearOfBirth; // Год рождения
- double academicPerformance; // Успеваемость (средняя оценка)
- };
- class Student
- {
- public:
- // Конструктор для инициализации с клавиатуры
- Student()
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- while (read() == 1) // Не удалось считать данные с клавиатуры
- {
- cerr << "Ошибка при инициализации. Попробовать ввести данные ещё раз? (y/n) ";
- char choice = 0;
- cin >> choice;
- if (choice == 'n')
- {
- cout << "Завершение работы программы" << endl;
- system("pause>nul");
- exit(1);
- }
- }
- }
- // Конструктор для инициализации из файла
- Student(string fileName)
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- if (loadFromFile(fileName) == 1) // Не удалось загрузить данные из файла
- {
- cerr << "Ошибка при инициализации. Не удаётся считать данные из файла.";
- cout << "Завершение работы программы" << endl;
- system("pause>nul");
- exit(1);
- }
- }
- // Деструктор
- ~Student()
- {
- clear(); // Удаляем все данные
- }
- // Удалить данные
- void clear()
- {
- if (students == NULL) // Если данные уже удалены или ещё не записаны
- return;
- // Освобождаем память
- delete[] students;
- students = NULL;
- size = 0;
- }
- // Ввод данных с клавиатуры
- int read()
- {
- cout << "Сколько студентов записать? "; // Запрашиваем число записей
- int n = 0;
- cin >> n;
- if (n <= 0) // Число записей введено некорректно
- {
- cerr << "Нельзя записать " << n << " студентов! Количество должно быть больше или равно нулю!" << endl;
- return 1;
- }
- clear(); // Очищаем старые данные
- size = n; // Выделяем память под новые
- students = new STUDENT[size];
- for (int i = 0; i < size; ++i) // Осуществляем запись
- {
- cout << "Студент № " << i + 1 << ": " << endl;
- cin.ignore(32767, '\n');
- cout << "Фамилия: "; getline(cin, students[i].name);
- cout << "Год рождения: "; cin >> students[i].yearOfBirth;
- cout << "Успеваемость: "; cin >> students[i].academicPerformance;
- }
- cout << "Данные записаны!" << endl;
- return 0;
- }
- // Загрузить данные из файла
- int loadFromFile(string fileName)
- {
- ifstream file(fileName); // Открываем файл на чтение
- if (!file.is_open()) // Ошибка при открытии файла
- {
- cerr << "Ошибка: Файл не может быть открыт!" << endl;
- return 1;
- }
- if (file.peek() == -1 || file.peek() == 0) // Файл пуст
- {
- cerr << "Ощибка: Файл пуст!" << endl;
- return 1;
- }
- // Начинаем загрузку данных
- cout << "Считываю данные из файла..." << endl;
- // Очищаем старые данные
- clear();
- // Вычисляем, сколько памяти потребуется выделить для загрузки содержимого файла (сколько будет записей в массиве)
- size = sizeofFile(&file) / 3;
- students = new STUDENT[size]; // Выделяем память
- for (int i = 0; i < size; ++i) // Загружаем данные
- {
- getline(file, students[i].name);
- file >> students[i].yearOfBirth;
- file >> students[i].academicPerformance;
- file.ignore(32767, '\n');
- }
- file.close(); // Закрываем файл
- cout << "Данные успешно загружены!" << endl;
- return 0;
- }
- // Вывод данных на экран
- void show()
- {
- cout << "Вывод данных на экран..." << endl;
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return;
- }
- // Выводим данные на жкран
- for (int i = 0; i < size; ++i)
- {
- cout << students[i].name << endl;
- cout << students[i].yearOfBirth << endl;
- cout << students[i].academicPerformance << endl;
- }
- }
- // Сохранить данные в файл
- int saveToFile(string fileName)
- {
- ofstream file(fileName); // Открываем файл на перезапись
- if (!file.is_open()) // Ошибка при открытии файла
- {
- cerr << "Файл не может быть открыт!\n" << endl;
- return 1;
- }
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return 1;
- }
- // Сохраняем данные
- cout << "Сохраняю данные..." << endl;
- for (int i = 0; i < size; i++)
- {
- file << students[i].name << endl;
- file << students[i].yearOfBirth << endl;
- if (i == size - 1)
- file << students[i].academicPerformance;
- else
- file << students[i].academicPerformance << endl;
- }
- cout << "Данные сохранены." << endl << endl;
- file.close(); // Закрываем файл
- }
- // Перегруженные методы для поиска
- int find(string nameToFind) // По фамилии (строка)
- {
- cout << "Поиск по фамилии..." << endl;
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return 1;
- }
- // Изначально считаем, что ничего не найдено
- bool foundSomething = false;
- for (int i = 0; i < size; ++i)
- {
- if (students[i].name.find(nameToFind) != string::npos) // Нашли частичное совпадение
- {
- // Выводим найденную запись
- cout << students[i].name << endl;
- cout << students[i].yearOfBirth << endl;
- cout << students[i].academicPerformance << endl;
- foundSomething = true; // Меняем значение флага
- }
- }
- if (foundSomething == false) // Если так ничего и не нашли
- cout << "Ничего не найдено!" << endl;
- return 0;
- }
- int find(int yearToFind) // По году рождения (целое число)
- {
- cout << "Поиск по году рождения..." << endl;
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return 1;
- }
- // Изначально считаем, что ничего не найдено
- bool foundSomething = false;
- for (int i = 0; i < size; ++i)
- {
- if (students[i].yearOfBirth == yearToFind) // Нашли полное совпадение
- {
- // Выводим найденную запись
- cout << students[i].name << endl;
- cout << students[i].yearOfBirth << endl;
- cout << students[i].academicPerformance << endl;
- foundSomething = true; // Меняем значение флага
- }
- }
- if (foundSomething == false) // Если так ничего и не нашли
- cout << "Ничего не найдено!" << endl;
- return 0;
- }
- int find(double performanceToFind) // По успеваемости (дробное число)
- {
- cout << "Поиск по успеваемости..." << endl;
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return 1;
- }
- // Изначально считаем, что ничего не найдено
- bool foundSomething = false;
- for (int i = 0; i < size; ++i)
- {
- if (students[i].academicPerformance == performanceToFind) // Нашли полное совпадение
- {
- // Выводим найденную запись
- cout << students[i].name << endl;
- cout << students[i].yearOfBirth << endl;
- cout << students[i].academicPerformance << endl;
- foundSomething = true; // Меняем значение флага
- }
- }
- if (foundSomething == false) // Если так ничего и не нашли
- cout << "Ничего не найдено!" << endl;
- return 0;
- }
- // Метод для сортировки
- void sort()
- {
- cout << "Сортировка..." << endl;
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return;
- }
- int choice = 0; // Уточняем у пользователя критерий сортировки
- cout << "Отсортировать по фамилии(1), году рождения(2) или по успеваемости(3)? (1/2/3)" << endl;
- do {
- cin >> choice;
- // Изначально считаем, что данные не отсортированы
- bool isSorted = false;
- switch (choice)
- {
- case 1: // Сортировка по фамилии (в алфавитном порядке)
- while (isSorted == false) // Пока данные не отсортированы
- {
- isSorted = true; // Предполагаем, что данные упорядочены
- for (int i = 0; i < size - 1; ++i)
- {
- string left = students[i].name;
- string right = students[i + 1].name;
- if (left > right) // Если оказывается, что данные неупорядочены
- {
- isSorted = false; // Изменяем значение флага
- // Меняем записи местами
- STUDENT tmp = students[i];
- students[i] = students[i + 1];
- students[i + 1] = tmp;
- }
- }
- }
- break;
- case 2: // Сортировка по году рождения (по возрастанию)
- while (isSorted == false) // Пока данные не отсортированы
- {
- isSorted = true; // Предполагаем, что данные упорядочены
- for (int i = 0; i < size - 1; ++i)
- {
- int left = students[i].yearOfBirth;
- int right = students[i + 1].yearOfBirth;
- if (left > right) // Если оказывается, что данные неупорядочены
- {
- isSorted = false; // Изменяем значение флага
- // Меняем записи местами
- STUDENT tmp = students[i];
- students[i] = students[i + 1];
- students[i + 1] = tmp;
- }
- }
- }
- break;
- case 3: // Сортировка по успеваемости (по возрастанию)
- while (isSorted == false) // Пока данные не отсортированы
- {
- isSorted = true; // Предполагаем, что данные упорядочены
- for (int i = 0; i < size - 1; ++i)
- {
- double left = students[i].academicPerformance;
- double right = students[i + 1].academicPerformance;
- if (left > right) // Если оказывается, что данные неупорядочены
- {
- isSorted = false; // Изменяем значение флага
- // Меняем записи местами
- STUDENT tmp = students[i];
- students[i] = students[i + 1];
- students[i + 1] = tmp;
- }
- }
- }
- break;
- default: // Пользователь ввёл неожиданное число
- cout << endl << endl;
- break;
- }
- // Не отпускаем пользователя, пока он корректно не выберет тип сортировки
- } while (choice < 0 || choice > 3);
- cout << "Данные отсортированы!" << endl;
- }
- // Добавить элемент в конец
- void add()
- {
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто! Введите данные с нуля! (пункт 1 или 2)" << endl;
- return;
- }
- cout << "Добавление элемента..." << endl;
- // Создаём временный массив для хранения существующих данных
- STUDENT * tmp = new STUDENT[size];
- for (int i = 0; i < size; ++i)
- tmp[i] = students[i];
- // Очищаем старый массив
- delete [] students;
- ++size; // Инкрементируем счётчик размера
- students = new STUDENT[size]; // Выделяем память под старые данные и один дополнительный элемент
- // Копируем старые данные обратно
- for (int i = 0; i < size-1; ++i)
- students[i] = tmp[i];
- // Очищаем временный массив
- delete [] tmp;
- tmp = NULL;
- // Осуществляем ввод нового элемента
- cout << "Студент № " << size << ": " << endl;
- cin.ignore(32767, '\n');
- cout << "Фамилия: "; getline(cin, students[size - 1].name);
- cout << "Год рождения: "; cin >> students[size - 1].yearOfBirth;
- cout << "Успеваемость: "; cin >> students[size - 1].academicPerformance;
- cout << "Элемент добавлен" << endl;
- }
- // Удалить последний элемент
- void remove()
- {
- if (students == NULL) // Если данных нет
- {
- cerr << "Пусто!" << endl;
- return;
- }
- cout << "Удаление элемента..." << endl;
- size--; // Декрементируем счётчик размеры
- if (size <= 0) // Если удалённая запись была последней
- clear(); // Безопасно удаляем все данные
- cout << "Элемент номер "<< size + 1 <<" удалён!" << endl;
- }
- private:
- STUDENT * students = NULL; // Указатель на динамический массив структур
- int size = 0; // Размер динамического массива
- };
- void showMenu(); // Объявление функции для вывода меню на экран
- // Точка входа
- int main()
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- const string fileName = "data.txt";
- Student * students = NULL;
- int choice = 0;
- cout << "Инициализация..." << endl;
- cout << "Ввести данные из файла (1) или вручную (2)? (1/2)" << endl;
- do {
- cin >> choice;
- switch (choice)
- {
- case 1:
- students = new Student(fileName);
- break;
- case 2:
- students = new Student();
- break;
- default:
- break;
- }
- cout << endl << endl;
- } while (students == NULL);
- choice = 0;
- showMenu();
- do {
- cin >> choice;
- string nameToFind = "";
- int yearToFind = 0;
- double performanceToFind = 0.0;
- switch (choice)
- {
- case 1:
- students->loadFromFile(fileName);
- break;
- case 2:
- students->read();
- break;
- case 3:
- students->saveToFile(fileName);
- break;
- case 4:
- students->show();
- break;
- case 5:
- cout << "Введите фамилию и инициалы: ";
- cin.ignore(32767, '\n');
- getline(cin, nameToFind);
- students->find(nameToFind);
- break;
- case 6:
- cout << "Введите год рождения: ";
- cin >> yearToFind;
- students->find(yearToFind);
- break;
- case 7:
- cout << "Введите успеваемость: ";
- cin >> performanceToFind;
- students->find(performanceToFind);
- break;
- case 8:
- students->sort();
- break;
- case 9:
- students->add();
- break;
- case 10:
- students->remove();
- break;
- case 11:
- showMenu();
- break;
- case 12:
- delete students;
- students = NULL;
- cout << "Завершение работы..." << endl;
- default:
- cout << endl << endl;
- break;
- }
- cout << "============================================================" << endl << endl;
- } while (choice != 12);
- delete students;
- students = NULL;
- system("pause>nul");
- return 0;
- }
- int sizeofFile(ifstream * file)
- {
- SetConsoleCP(1251);
- SetConsoleOutputCP(1251);
- int n = 0;
- string tmp;
- while (!file->eof())
- {
- *file >> tmp;
- ++n;
- }
- file->seekg(0); // Возвращаем курсор в начало файла
- return n;
- }
- // Описание функции для вывода меню на экран
- void showMenu()
- {
- cout << "=========================== Меню ===========================" << endl;
- cout << "Введите 1, чтобы загрузить данные." << endl;
- cout << "Введите 2, чтобы ввести данные." << endl;
- cout << "Введите 3, чтобы сохранить данные." << endl;
- cout << "Введите 4, чтобы вывести данные." << endl << endl;
- cout << "Введите 5, чтобы найти студентов по фамилии." << endl;
- cout << "Введите 6, чтобы найти студентов по году рождения." << endl;
- cout << "Введите 7, чтобы найти студентов по успеваемости." << endl << endl;
- cout << "Введите 8 чтобы отсортировать данные." << endl << endl;
- cout << "Введите 9, чтобы добавить элемент в конец." << endl;
- cout << "Введите 10, чтобы удалить последний элемент." << endl << endl;
- cout << "Введите 11, чтобы показать меню." << endl;
- cout << "Введите 12, чтобы выйти." << endl;
- cout << "============================================================" << endl;
- cout << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement