Lesson 20 of 20Practical Modern C++40 min

Final Project: Student Record Manager

This final project combines the main ideas from the course. You will build a menu-driven Student Record Manager that stores records in a vector, validates marks, sorts data, searches by ID, and saves records to a text file.

Project Features

Complete Program

StudentRecordManager.cpp
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

class Student
{
private:
    string id;
    string name;
    double mark;

public:
    Student(string studentId, string studentName, double studentMark)
        : id(studentId), name(studentName), mark(studentMark)
    {
    }

    const string& getId() const { return id; }
    const string& getName() const { return name; }
    double getMark() const { return mark; }
};

double readValidMark()
{
    double mark;

    while (true)
    {
        cout << "Enter mark (0-100): ";

        if (cin >> mark && mark >= 0 && mark <= 100)
        {
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            return mark;
        }

        cout << "Invalid mark. Please try again.
";
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
}

void addStudent(vector<Student>& students)
{
    string id;
    string name;

    cout << "Enter student ID: ";
    getline(cin, id);

    auto duplicate = find_if(students.begin(), students.end(),
        [&id](const Student& student)
        {
            return student.getId() == id;
        });

    if (duplicate != students.end())
    {
        cout << "That student ID already exists.
";
        return;
    }

    cout << "Enter student name: ";
    getline(cin, name);

    double mark = readValidMark();
    students.emplace_back(id, name, mark);
    cout << "Student added.
";
}

void listStudents(const vector<Student>& students)
{
    if (students.empty())
    {
        cout << "No student records are available.
";
        return;
    }

    cout << left << setw(12) << "ID"
         << setw(24) << "Name"
         << right << setw(8) << "Mark" << '\n';
    cout << string(44, '-') << '\n';

    for (const Student& student : students)
    {
        cout << left << setw(12) << student.getId()
             << setw(24) << student.getName()
             << right << setw(8) << fixed << setprecision(1)
             << student.getMark() << '\n';
    }
}

void searchStudent(const vector<Student>& students)
{
    string id;
    cout << "Enter student ID to search: ";
    getline(cin, id);

    auto result = find_if(students.begin(), students.end(),
        [&id](const Student& student)
        {
            return student.getId() == id;
        });

    if (result == students.end())
    {
        cout << "Student not found.
";
        return;
    }

    cout << "Name: " << result->getName() << '\n';
    cout << "Mark: " << result->getMark() << '\n';
}

void sortByMark(vector<Student>& students)
{
    sort(students.begin(), students.end(),
        [](const Student& a, const Student& b)
        {
            return a.getMark() > b.getMark();
        });

    cout << "Records sorted from highest to lowest mark.
";
}

void saveStudents(const vector<Student>& students)
{
    ofstream file("students.txt");

    for (const Student& student : students)
    {
        file << student.getId() << '|'
             << student.getName() << '|'
             << student.getMark() << '\n';
    }
}

void loadStudents(vector<Student>& students)
{
    ifstream file("students.txt");
    string line;

    while (getline(file, line))
    {
        stringstream record(line);
        string id;
        string name;
        string markText;

        if (getline(record, id, '|') &&
            getline(record, name, '|') &&
            getline(record, markText))
        {
            students.emplace_back(id, name, stod(markText));
        }
    }
}

int main()
{
    vector<Student> students;
    loadStudents(students);

    int choice;

    do
    {
        cout << "
Student Record Manager
";
        cout << "1. Add student
";
        cout << "2. List students
";
        cout << "3. Search by ID
";
        cout << "4. Sort by mark
";
        cout << "0. Save and exit
";
        cout << "Choose an option: ";

        if (!(cin >> choice))
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Please enter a number.
";
            continue;
        }

        cin.ignore(numeric_limits<streamsize>::max(), '\n');

        switch (choice)
        {
            case 1: addStudent(students); break;
            case 2: listStudents(students); break;
            case 3: searchStudent(students); break;
            case 4: sortByMark(students); break;
            case 0:
                saveStudents(students);
                cout << "Records saved. Goodbye.
";
                break;
            default:
                cout << "Invalid choice.
";
        }
    } while (choice != 0);

    return 0;
}

Suggested Improvements

Course complete

You now have a foundation that covers syntax, control flow, functions, collections, object-oriented programming, memory safety, files, algorithms, debugging, and a complete console project.

Lesson Summary

Combine classes, vectors, functions, validation, files, and algorithms in one project.