#include <iostream>
#include <string>
#include <fstream>
using namespace std;What's happening here:
iostream: For input/output operations (cin, cout)string: For string data type and string operationsfstream: For file operations (reading/writing files)using namespace std: Avoids writing std:: before every standard library functionprivate:
string id;
string name;
int age;
string dateofbirth;
string placeofbirth;
string className;
string major;
string phonenumber;
string address;Design Decision: All data is private (encapsulation principle)
Student() {}Purpose: Creates an empty student object with default values
Student(string i, string n, int a, string d, string pl, string c, string m, string p, string ad) {
id = i;
name = n;
age = a;
dateofbirth = d;
placeofbirth = pl;
className = c;
major = m;
phonenumber = p;
address = ad;
}Purpose: Creates a student object with all fields initialized at once
string getId() const { return id; }
string getName() const { return name; }
int getAge() const { return age; }
// ... more gettersKey Points:
const keyword: Method doesn't modify the objectvoid setName(string n) { name = n; }
void setAge(int a) { age = a; }
void setDateofbirth(string d) { dateofbirth = d; }
// ... more settersKey Points:
void display(int index) const {
cout << "Student[" << (index + 1) << "] ID: " << id << "\n";
cout << "Student[" << (index + 1) << "] Name: " << name << "\n";
cout << "Student[" << (index + 1) << "] Age: " << age << "\n";
// ... more output lines
cout << "-----------------------------\n";
}What's happening:
(index + 1) converts 0-based array index to 1-based displayconst method - doesn't modify the objectprivate:
static const int MAX = 100;
Student students[MAX];
int numStudents = 0;Breakdown:
static const int MAX = 100: Compile-time constant, shared by all instancesStudent students[MAX]: Fixed-size array of Student objectsint numStudents = 0: Tracks how many students are actually storedvoid welcomeMsg() {
cout << "============================\n";
cout << " Welcome to Student System \n";
cout << "============================\n";
}void displayMenu() {
cout << "\nMenu:\n";
cout << "1. Add Student(s)\n";
cout << "2. Display All Students\n";
// ... more options
cout << "Enter your choice: ";
}Purpose: User interface methods that provide clear navigation
void addStudent() {
int count;
cout << "===== Add Student(s) =====\n";
cout << "Enter number of students to add: ";
cin >> count;
for (int i = 0; i < count && numStudents < MAX; i++) {What's happening:
count times OR until array is full (whichever comes first)numStudents < MAX prevents array overflowstring id, name, studentClass, studentMajor, studentPhoneNumber, studentDateofbirth, studentPlaceofbirth, studentAddress;
int age;
cout << "Enter Student[" << (numStudents + 1) << "] ID: ";
cin >> id;
cin.ignore();
cout << "Enter Student[" << (numStudents + 1) << "] Name: ";
getline(cin, name);Critical Detail: cin.ignore()
cin >> id, a newline character remains in the buffercin.ignore() removes this newlinegetline() would read an empty stringstudents[numStudents++] = Student(id, name, age, studentDateofbirth, studentPlaceofbirth, studentClass, studentMajor, studentPhoneNumber, studentAddress);
cout << "Student[" << numStudents << "] added successfully.\n";What's happening:
numStudentsnumStudents++ increments the counter after using the valuevoid displayStudents() {
cout << "===== Display All Students =====\n";
if (numStudents == 0) {
cout << "No students to display.\n";
return;
}
for (int i = 0; i < numStudents; i++) {
students[i].display(i);
}
}Logic Flow:
string toLowerCase(string str) {
for (char &c : str) {
c = tolower(c);
}
return str;
}Range-based for loop:
char &c : str - for each character reference in the string&c means we're modifying the original character, not a copytolower(c) converts character to lowercasevoid searchStudent() {
string key;
cout << "===== Search Student =====\n";
cout << "Enter Student ID or Name to search: ";
cin.ignore();
getline(cin, key);
string keyLower = toLowerCase(key);
bool found = false;Setup:
found flag tracks if we find any matchesfor (int i = 0; i < numStudents; i++) {
string idLower = toLowerCase(students[i].getId());
string nameLower = toLowerCase(students[i].getName());
if (idLower.find(keyLower) != string::npos || nameLower.find(keyLower) != string::npos) {
cout << "Student found at index [" << (i+1) << "]:\n";
students[i].display(i);
found = true;
}
}Key Concepts:
string::find() returns position of substring, or string::npos if not foundstring::npos is a special value meaning "not found"|| operator: if EITHER ID or name contains the search termvoid updateStudent() {
string id;
cout << "===== Update Student =====\n";
cout << "Enter Student ID to update: ";
cin >> id;
for (int i = 0; i < numStudents; i++) {
if (students[i].getId() == id) {
// Get new values from user
// Update the student object
// Return from function
}
}
cout << "Student not found.\n";
}Logic:
void deleteStudent() {
string id;
// ... get ID from user
for (int i = 0; i < numStudents; i++) {
if (students[i].getId() == id) {
for (int j = i; j < numStudents - 1; j++) {
students[j] = students[j + 1];
}
numStudents--;
cout << "Student deleted successfully.\n";
return;
}
}
}Array Shifting Logic:
ii+1 to end one position leftnumStudents countervoid saveToFile() {
string fileName;
cout << "Enter the file name: ";
cin.ignore();
getline(cin, fileName);
fileName += ".txt";
ofstream outFile(fileName);
if (!outFile) {
cout << "Error: Could not create file for writing.\n";
return;
}File Operations:
ofstream: Output file stream for writingfileName += ".txt": Automatic extension additionif (!outFile): Checks if file creation failedwhile (getline(inFile, id) && numStudents < MAX) {
if (!getline(inFile, name)) break;
if (!(inFile >> age)) break;
inFile.ignore();
if (!getline(inFile, dateofbirth)) break;
// ... continue reading other fields
students[numStudents++] = Student(id, name, age, ...);
}Complex Reading Logic:
getline(inFile, id) reads a line into id&& ensures we don't exceed array boundsif (!getline(...)) checks if reading failedinFile >> age reads integer, inFile.ignore() removes newlinebreak exits the loopvoid sortStudents() {
// ... check if students exist
for (int i = 0; i < numStudents - 1; i++) {
for (int j = 0; j < numStudents - i - 1; j++) {
if (students[j].getName() > students[j + 1].getName()) {
Student temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
}
}
}Bubble Sort Algorithm:
i controls number of passesj compares adjacent elementsnumStudents - i - 1: Optimization (sorted elements don't need rechecking)students[j].getName() > students[j + 1].getName(): Lexicographic comparisonvoid run() {
welcomeMsg();
int choice;
do {
displayMenu();
cin >> choice;
switch (choice) {
case 1: addStudent(); break;
case 2: displayStudents(); break;
// ... more cases
case 9: cout << "Exiting program.\n"; break;
default: cout << "Invalid choice. Try again.\n";
}
} while (choice != 9);
}
int main() {
StudentDatabase db;
db.run();
return 0;
}Program Structure:
do-while loop: Menu displays at least onceswitch-case: Clean way to handle multiple menu optionsdefault case: Handles invalid input gracefullymain() creates database object and starts the programcin.ignore() after integer inputnumStudents < MAXPerfect for understanding how object-oriented programming solves real problems!