C++ Student Grade System Project
Record scores for a class, compute averages, and assign letter grades.
What you will build
Enter students and their scores, then compute each student's average, letter grade, and the class statistics. It's a gentle introduction to processing a whole collection of records — the seed of every gradebook, payroll, and report tool.
What you will learn
- Storing records in arrays/vectors of structs
- Computing averages and finding min/max
- Mapping numeric ranges to letter grades
- Producing a formatted summary report
Feature checklist
- Add multiple students with several subject scores
- Per-student average and letter grade (A–F)
- Class average, highest, and lowest score
- Neatly aligned report table
- Count of students passing (average ≥ 50)
Starter code
#include <iostream>
#include <vector>
#include <string>
struct Student {
std::string name;
std::vector<int> scores;
double average() const {
double sum = 0;
for (int s : scores) sum += s;
return scores.empty() ? 0 : sum / scores.size();
}
};
char gradeOf(double avg) {
if (avg >= 90) return 'A';
if (avg >= 80) return 'B';
if (avg >= 70) return 'C';
if (avg >= 60) return 'D';
return 'F';
}
int main() {
std::vector<Student> cls = {
{"Ada", {92, 88, 95}}, {"Bola", {64, 71, 58}}, {"Chidi", {77, 83, 80}}
};
for (const auto& s : cls)
std::cout << s.name << ": avg " << s.average()
<< " -> grade " << gradeOf(s.average()) << "\n";
}Full walkthrough
Step 1: Model a student with a member function
struct Student holds a name and a std::vector<int> of scores — a vector because students may have different numbers of subjects. Its average() member function sums the scores and divides by the count, returning 0 for an empty list so a student with no scores cannot trigger a division by zero. Keeping average() ON the struct means main() never repeats that loop.
Step 2: Write gradeOf() as a threshold ladder
gradeOf(double avg) returns 'A' at 90+, 'B' at 80+, 'C' at 70+, 'D' at 60+, else 'F'. Like the BMI categories, each if only states its lower bound because the returns above it have already handled the higher bands. Write it once, use it everywhere — report, honours list, pass count.
char gradeOf(double avg) {
if (avg >= 90) return 'A';
if (avg >= 80) return 'B';
if (avg >= 70) return 'C';
if (avg >= 60) return 'D';
return 'F';
}Step 3: Seed example data so you can see output immediately
The starter's main() builds the class with an initializer list — Ada {92, 88, 95}, Bola {64, 71, 58}, Chidi {77, 83, 80} — and prints each student's average and grade. Starting from known data lets you verify average() by hand (Ada: 275/3 = 91.7 → A) before you wire up any input code.
Step 4: Replace the seed data with real input
Ask how many students, then for each: read a name with std::getline, ask how many subjects, and loop reading that many scores. Push each finished Student into the vector. Validate scores are 0–100 as you read them — a 105 quietly poisons every statistic the report prints.
Step 5: Compute the class statistics in one pass
Loop over all students once, tracking the sum of averages (for the class average), the highest and lowest average seen, and a pass counter for average >= 50. One pass, four answers. Resist computing these in separate loops over the class — the single-accumulator pattern is the skill this project is really teaching.
Step 6: Print an aligned report
Use std::setw from <iomanip> so names and numbers line up in columns, print each student's average to one decimal with their grade, then the summary block: class average, highest, lowest, and how many passed. A report nobody can read at a glance fails its only job, so the formatting IS a feature here.
Step 7: Test with the seeded class first
Before typing your own data, the seeded class must produce: Ada 91.7 A, Bola 64.3 D, Chidi 80.0 B, class average 78.7, 3 passing. If your hand-check disagrees with the program, believe your hand-check and find the bug — that habit is worth more than the program.
Common mistakes
- Dividing the score sum by a hard-coded subject count instead of scores.size(), breaking the moment subjects differ per student.
- Averaging integer scores with integer division (int sum / int count), truncating 91.67 to 91 before the grade is chosen.
- Counting a pass as score >= 50 on ONE subject instead of on the student's average, as the checklist specifies.
Compile and run
g++ -std=c++17 -o grades grades.cppSample run
$ ./grades
Student 1 name:
> Ada
Scores (3 subjects):
> 92 88 95
Student 2 name:
> Bola
Scores (3 subjects):
> 64 71 58
Student 3 name:
> Chidi
> 77 83 80
Name Avg Grade
Ada 91.7 A
Bola 64.3 D
Chidi 80.0 B
Class average: 78.7
Highest: Ada (91.7)
Lowest: Bola (64.3)
Passing (avg >= 50): 3 of 3Try it in your browser
No browser demo is included for this project. Build the C++ version below — that is the real program.