C++ DEVELOPMENT

Building a Console Hospital System

Apr 20, 2025 9 min read MH4S33B
Hospital

An educational dive into file handling, data structures, and clean UI design

🩺 Why I Built This Project

As a programmer constantly looking to grow and take on practical challenges, I wanted to create something that mirrors real-world utility — something more than just solving problems on online judges. That’s when I thought: why not a Hospital Management System? It’s relevant, data-heavy, and a great playground for practicing file I/O, data validation, and structured programming in C++.

This console-based system isn’t just about handling patient records — it’s about applying core concepts in a meaningful way. From CRUD operations to persistent file storage, this project helped me sharpen my skills while giving me something tangible to show.

🛠️ Features at a Glance

  • ✅ Add, view, update, delete records
  • 🔍 Search by ID or name
  • 💾 Persistent storage (patients.dat)
  • 🛡️ Input validation (ID, Age)
  • 💻 Clean console interface

📁 File Structure

.
├── hospital_management.cpp
├── patients.dat
└── README.md

🚀 Getting Started

# Compile and Run

g++ hospital_management.cpp -o hospital_management

./hospital_management

🔧 Code Walkthrough

1. Structs and Constants

First things first — we need a way to structure our patient data. Instead of jumping into classes right away, I opted for a struct-based approach for simplicity.

const int MAX_PATIENTS = 100;

struct Patient {
    int id;
    string name;
    int age;
    string disease;
    string contact;
};

2. Cleaning Up the Console

To keep the user interface clean and readable, I added a clearScreen() function:

void clearScreen() {
    system("cls"); // Windows
    // system("clear"); // Mac/Linux
}

3. Adding a New Patient

This part of the code allows the user to input a new patient’s details, with built-in validation for duplicate IDs and age:

void addPatient(Patient patients[], int& count) {
    if (count >= MAX_PATIENTS) {
        cout << "No space to add more patients.\n";
        return;
    }

    cout << "\nEnter Patient Details:\n";
    
    // Check for duplicate ID
    bool idExists;
    do {
        cout << "ID: ";
        cin >> patients[count].id;
        // ... validation loop ...
    } while (idExists);

    cout << "Name: ";
    cin.ignore();
    getline(cin, patients[count].name);
    // ... get other details ...
}

4. Viewing All Patients

Once we’ve added patients, we need a way to display them. This function lists all existing records in a clean format:

void displayPatients(Patient patients[], int count) {
    if (count == 0) {
        cout << "No patients to display.\n";
        return;
    }

    cout << "\n--- Patient Details ---\n";
    for (int i = 0; i < count; i++) {
        cout << "ID: " << patients[i].id << "\n";
        cout << "Name: " << patients[i].name << "\n";
        cout << "Age: " << patients[i].age << "\n";
        cout << "Disease: " << patients[i].disease << "\n";
        cout << "Contact: " << patients[i].contact << "\n";
        cout << "----------------------\n";
    }
}

5. Updating Patient Details

Sometimes, information changes. Here’s how updates work, allowing selective editing based on ID:

void updatePatient(Patient patients[], int count) {
    int id;
    cout << "\nEnter Patient ID to update: ";
    cin >> id;

    for (int i = 0; i < count; i++) {
        if (patients[i].id == id) {
            cout << "\nCurrent Details:\n";
            cout << "1. Name: " << patients[i].name << "\n";
            // ... display other fields ...

            int choice;
            cout << "\nEnter field to update (1-4): ";
            cin >> choice;
            
            // ... switch case to update specific field ...
            cout << "Updated successfully!\n";
            return;
        }
    }
    cout << "Patient not found.\n";
}

6. Deleting Patient Records

Whether it’s a mistake or someone’s data needs to be removed — this function handles it by shifting array elements:

void removePatient(Patient patients[], int& count) {
    int id;
    cout << "\nEnter Patient ID to remove: ";
    cin >> id;

    for (int i = 0; i < count; i++) {
        if (patients[i].id == id) {
            // Shift elements left
            for (int j = i; j < count - 1; j++) {
                patients[j] = patients[j + 1];
            }
            count--;
            cout << "Patient removed successfully!\n";
            return;
        }
    }
    cout << "Patient not found.\n";
}

7. Searching for a Patient

One of the most useful features. Search by ID or Name using string matching:

void searchPatient(Patient patients[], int count) {
    string searchTerm;
    cout << "Enter name or ID: ";
    cin >> searchTerm;

    bool found = false;
    for (int i = 0; i < count; i++) {
        if (to_string(patients[i].id) == searchTerm || 
            patients[i].name.find(searchTerm) != string::npos) {
            
            cout << "ID: " << patients[i].id << "\n";
            cout << "Name: " << patients[i].name << "\n";
            // ... print other fields ...
            found = true;
        }
    }

    if (!found) {
        cout << "No matching patients found.\n";
    }
}

8. Saving Data to File

Data persistence is key. Here’s how we make sure patient data doesn’t vanish when the program closes:

void saveToFile(Patient patients[], int count) {
    ofstream file("patients.dat");
    if (!file) {
        cout << "Error saving data.\n";
        return;
    }

    for (int i = 0; i < count; i++) {
        file << patients[i].id << '\n'
             << patients[i].name << '\n'
             << patients[i].age << '\n'
             << patients[i].disease << '\n'
             << patients[i].contact << '\n';
    }
    cout << "Data saved successfully!\n";
}

9. Loading Records from File

When the program starts, it automatically loads available data:

void loadFromFile(Patient patients[], int& count) {
    ifstream file("patients.dat");
    if (!file) {
        cout << "No existing data found.\n";
        return;
    }

    count = 0;
    while (file >> patients[count].id) {
        file.ignore(); // Skip newline
        getline(file, patients[count].name);
        file >> patients[count].age;
        file.ignore();
        getline(file, patients[count].disease);
        getline(file, patients[count].contact);
        count++;
    }
    cout << "Data loaded successfully!\n";
}

🧠 10. The Main Menu

This is where everything connects. The main() function handles navigation between features:

int main() {
    Patient patients[MAX_PATIENTS];
    int patientCount = 0;
    
    loadFromFile(patients, patientCount);

    int choice;
    do {
        clearScreen();
        cout << "\n--- Hospital Management System ---\n";
        cout << "1. Add New Patient\n";
        cout << "2. Display All Patients\n";
        // ... other options ...
        cout << "7. Exit\n";
        
        cout << "Enter your choice: ";
        cin >> choice;

        switch (choice) {
            case 1: addPatient(patients, patientCount); break;
            case 2: displayPatients(patients, patientCount); break;
            // ... cases for update, delete, search, save ...
            case 7: saveToFile(patients, patientCount); break;
        }
    } while (choice != 7);

    return 0;
}

🚧 Future Improvements

  • Admin Login: Password protection for sensitive actions.
  • Appointments: Scheduling system with time slots.
  • Database: Moving from file I/O to SQLite/MySQL.

🎯 Final Thoughts

This Hospital Management System may seem simple, but it packs a lot of core programming concepts: File handling, Input validation, and Modular programming. If you’re learning C++, this is a great project to solidify your understanding.

View Source Code