Загрузка данных
List.h
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
struct Grade {
string subject;
string date;
int mark;
};
struct Student {
string number;
string last_name;
string birth_day;
string group;
vector<Grade> results;
};
struct Node {
Student item;
Node* next;
};
class List {
private:
Node* head;
int size;
void clear();
Node* getNodeByIndex(int index);
public:
List();
List(const List& other);
~List();
List& operator=(const List& other);
void addToStart(const Student& s);
void addAfterIndex(int index, const Student& s);
void deleteNFromIndex(int index, int n);
void loadFromFile(const string& filename);
void addFromKeyboard();
List findByBirthDate(const string& birthDate);
double averageMarkBySubject(const string& studentNumber, const string& subject);
void saveToFile(const string& filename) const;
void print() const;
int getSize() const;
friend ostream& operator<<(ostream& os, const List& list);
};
------------------------------------------------------------------
List.cpp
#include "List.h"
void List::clear() {
Node* temp = head;
while (temp) {
Node* next = temp->next;
delete temp;
temp = next;
}
head = nullptr;
size = 0;
}
Node* List::getNodeByIndex(int index) {
if (index < 0 || index >= size) return nullptr;
Node* temp = head;
for (int i = 0; i < index; i++) temp = temp->next;
return temp;
}
List::List() : head(nullptr), size(0) {}
List::List(const List& other) : head(nullptr), size(0) {
Node* temp = other.head;
while (temp) {
Node* newNode = new Node{temp->item, nullptr};
if (!head) head = newNode;
else {
Node* t = head;
while (t->next) t = t->next;
t->next = newNode;
}
size++;
temp = temp->next;
}
}
List::~List() {
clear();
}
List& List::operator=(const List& other) {
if (this != &other) {
clear();
Node* temp = other.head;
while (temp) {
Node* newNode = new Node{temp->item, nullptr};
if (!head) head = newNode;
else {
Node* t = head;
while (t->next) t = t->next;
t->next = newNode;
}
size++;
temp = temp->next;
}
}
return *this;
}
void List::addToStart(const Student& s) {
Node* newNode = new Node{s, head};
head = newNode;
size++;
}
void List::addAfterIndex(int index, const Student& s) {
if (index < 0 || index >= size) return;
Node* current = getNodeByIndex(index);
if (!current) return;
Node* newNode = new Node{s, current->next};
current->next = newNode;
size++;
}
void List::deleteNFromIndex(int index, int n) {
if (index < 0 || index >= size || n <= 0) return;
if (index == 0) {
for (int i = 0; i < n && head; i++) {
Node* temp = head;
head = head->next;
delete temp;
size--;
}
return;
}
Node* prev = getNodeByIndex(index - 1);
if (!prev) return;
Node* current = prev->next;
int deleted = 0;
while (current && deleted < n) {
Node* temp = current;
current = current->next;
delete temp;
deleted++;
size--;
}
prev->next = current;
}
void List::loadFromFile(const string& filename) {
ifstream file(filename);
if (!file) return;
int n;
file >> n;
for (int i = 0; i < n; i++) {
Student s;
int m;
file >> s.number >> s.last_name >> s.birth_day >> s.group;
file >> m;
for (int j = 0; j < m; j++) {
Grade g;
file >> g.subject >> g.date >> g.mark;
s.results.push_back(g);
}
addToStart(s);
}
file.close();
}
void List::addFromKeyboard() {
Student s;
int m;
cout << "Number: "; cin >> s.number;
cout << "Last name: "; cin >> s.last_name;
cout << "Birth day: "; cin >> s.birth_day;
cout << "Group: "; cin >> s.group;
cout << "Grades count: "; cin >> m;
for (int i = 0; i < m; i++) {
Grade g;
cout << "Subject: "; cin >> g.subject;
cout << "Date: "; cin >> g.date;
cout << "Mark: "; cin >> g.mark;
s.results.push_back(g);
}
addToStart(s);
}
List List::findByBirthDate(const string& birthDate) {
List result;
Node* temp = head;
while (temp) {
if (temp->item.birth_day == birthDate) {
Node* newNode = new Node{temp->item, nullptr};
if (!result.head) result.head = newNode;
else {
Node* t = result.head;
while (t->next) t = t->next;
t->next = newNode;
}
result.size++;
}
temp = temp->next;
}
return result;
}
double List::averageMarkBySubject(const string& studentNumber, const string& subject) {
Node* temp = head;
while (temp) {
if (temp->item.number == studentNumber) {
int sum = 0, count = 0;
for (const auto& g : temp->item.results) {
if (g.subject == subject) {
sum += g.mark;
count++;
}
}
if (count == 0) return 0.0;
return static_cast<double>(sum) / count;
}
temp = temp->next;
}
return 0.0;
}
void List::saveToFile(const string& filename) const {
ofstream file(filename);
if (!file) return;
file << size << "\n";
Node* temp = head;
while (temp) {
file << temp->item.number << " " << temp->item.last_name << " "
<< temp->item.birth_day << " " << temp->item.group << "\n";
file << temp->item.results.size() << "\n";
for (const auto& g : temp->item.results) {
file << g.subject << " " << g.date << " " << g.mark << "\n";
}
temp = temp->next;
}
file.close();
}
void List::print() const {
Node* temp = head;
int idx = 0;
while (temp) {
cout << "[" << idx << "] " << temp->item.last_name << " (" << temp->item.number << ") "
<< temp->item.group << " " << temp->item.birth_day << "\n";
for (const auto& g : temp->item.results) {
cout << " " << g.subject << " (" << g.date << "): " << g.mark << "\n";
}
temp = temp->next;
idx++;
}
}
int List::getSize() const {
return size;
}
ostream& operator<<(ostream& os, const List& list) {
Node* temp = list.head;
int idx = 0;
while (temp) {
os << "[" << idx << "] " << temp->item.last_name << " (" << temp->item.number << ")\n";
temp = temp->next;
idx++;
}
return os;
}
--------------------
main.cpp
#include "List.h"
#include <Windows.h>
#include <cstdlib>
int main(int argc, char* argv[]) {
system("chcp 65001 > nul");
SetConsoleOutputCP(65001);
SetConsoleCP(65001);
string filename = "data.txt";
if (argc > 1) filename = argv[1];
List list;
list.loadFromFile(filename);
cout << "Initial list:\n" << list << "\n";
cout << "Add after index 1:\n";
Student s{"200", "Testov", "10.10.2004", "101-И", {{"Alg", "01.01.2025", 5}}};
list.addAfterIndex(1, s);
cout << "After add:\n" << list << "\n";
cout << "Delete 2 nodes from index 0:\n";
list.deleteNFromIndex(0, 2);
cout << "After delete:\n" << list << "\n";
string bDate;
cout << "Enter birth date to search: ";
cin >> bDate;
List found = list.findByBirthDate(bDate);
cout << "Found by date " << bDate << ":\n" << found << "\n";
string sNum, subj;
cout << "Enter student number: ";
cin >> sNum;
cout << "Enter subject: ";
cin >> subj;
double avg = list.averageMarkBySubject(sNum, subj);
cout << "Average: " << avg << "\n";
list.saveToFile("output.txt");
cout << "Saved to file.\n";
return 0;
}
--------------------------------------
data.txt
5
101 Иванов 15.05.2004 101-И
2
Математика 10.10.2025 4
Физика 12.10.2025 3
102 Петров 20.03.2004 101-И
1
История 11.10.2025 5
103 Сидоров 01.07.2003 102-И
3
Математика 10.10.2025 3
Программирование 11.10.2025 2
Физика 12.10.2025 4
104 Кузнецов 14.12.2004 102-И
2
Физика 12.10.2025 3
Математика 15.10.2025 3
105 Смирнова 15.05.2004 101-И
1
История 11.10.2025 5