Project Progress
0%
Capstone Project  ยท  Structs + Files + Menu-Driven Design

Hospital Management System

A complete, menu-driven C program that manages patient admissions โ€” bed allocation, doctor assignment, discharge billing, search, and saving records to a file.

Patient struct & beds
Admit & search
Discharge & billing
File saving
Main menu
๐Ÿ“–

Project Overview

Each hospital bed is a struct holding its bed number, occupancy status, and โ€” once a patient is admitted โ€” the patient's name, age, disease, assigned doctor, and how many days they've stayed. The hospital itself is just an array of these beds.

  • Display All Beds โ€” prints a formatted ward status table
  • Admit a Patient โ€” assigns a patient and doctor to a free bed
  • Discharge a Patient โ€” calculates the total bill and frees the bed
  • Search Patient โ€” looks up which bed a patient is in, by bed number
  • Save to File โ€” writes all bed/patient records to a text file
Concept usedWhere
structBed record: bed no, occupancy, patient, age, disease, doctor, days
ArraysBed ward[TOTAL_BEDS] holds every bed in the hospital
FunctionsOne function per menu operation โ€” keeps main() clean
switch-caseRoutes the user's menu choice to the right function
File I/Ofopen/fprintf to persist ward data
Billing logicRoom charge + doctor fee, combined at discharge
part 1
1

Bed Struct & Ward Initialization

Data model

Instead of modeling "patients" as a free-floating list, this project models beds as the fixed resource โ€” exactly like rooms in the Hotel project. A patient only exists in the system while occupying a bed. initWard() sets up 5 beds, all empty.

Part 1 ยท hospital.c โ€” structs & setup
hospital.c
C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define TOTAL_BEDS 5
#define ROOM_CHARGE_PER_DAY 800.0
#define DOCTOR_FEE_PER_DAY 500.0

typedef struct {
    int  bedNo;
    int  isOccupied;
    char patientName[40];
    int  age;
    char disease[40];
    char doctor[30];
    int  daysAdmitted;
} Bed;

Bed ward[TOTAL_BEDS];   // the entire ward lives in this array

void initWard() {
    for (int i = 0; i < TOTAL_BEDS; i++) {
        ward[i].bedNo = 1 + i;
        ward[i].isOccupied = 0;
        strcpy(ward[i].patientName, "-");
        ward[i].age = 0;
        strcpy(ward[i].disease, "-");
        strcpy(ward[i].doctor, "-");
        ward[i].daysAdmitted = 0;
    }
}
๐Ÿ’ก Beds, not patients, are the array. This mirrors real hospital software design: bed availability is the scarce resource being scheduled, and a patient record is just data attached to a bed for as long as they occupy it.
part 2
2

Display, Search & Admit a Patient

Core operations

findBedIndex() is the shared helper โ€” same role as findRoomIndex() in the Hotel project and findBookIndex() in the Library project. It's the same pattern every time: turn a user-facing ID into an array index, then check availability before touching anything.

Part 2 ยท hospital.c โ€” display, search, admit
hospital.c
C
void displayWard() {
    printf("\n%-5s %-10s %-18s %-5s %-14s %-12s\n",
           "Bed", "Status", "Patient", "Age", "Disease", "Doctor");
    for (int i = 0; i < TOTAL_BEDS; i++) {
        printf("%-5d %-10s %-18s %-5d %-14s %-12s\n",
               ward[i].bedNo, ward[i].isOccupied ? "Occupied" : "Free",
               ward[i].patientName, ward[i].age, ward[i].disease, ward[i].doctor);
    }
}

int findBedIndex(int bedNo) {
    for (int i = 0; i < TOTAL_BEDS; i++)
        if (ward[i].bedNo == bedNo)
            return i;
    return -1;
}

int findFreeBed() {
    for (int i = 0; i < TOTAL_BEDS; i++)
        if (!ward[i].isOccupied)
            return i;
    return -1;   // ward is full
}

void admitPatient() {
    int idx = findFreeBed();
    if (idx == -1) { printf("Ward full. No beds available.\n"); return; }

    printf("Enter patient name: ");
    scanf(" %[^\n]", ward[idx].patientName);
    printf("Enter age: ");
    scanf("%d", &ward[idx].age);
    printf("Enter disease/reason for admission: ");
    scanf(" %[^\n]", ward[idx].disease);
    printf("Enter assigned doctor's name: ");
    scanf(" %[^\n]", ward[idx].doctor);

    ward[idx].isOccupied = 1;
    ward[idx].daysAdmitted = 0;

    printf("\nPatient %s admitted to Bed %d under Dr. %s.\n",
           ward[idx].patientName, ward[idx].bedNo, ward[idx].doctor);
}

void searchPatient() {
    int bedNo;
    printf("Enter bed number to check: ");
    scanf("%d", &bedNo);

    int idx = findBedIndex(bedNo);
    if (idx == -1) { printf("Bed not found.\n"); return; }

    if (!ward[idx].isOccupied) {
        printf("Bed %d is currently free.\n", bedNo);
        return;
    }
    printf("Bed %d | %s, Age %d | %s | Dr. %s\n",
           ward[idx].bedNo, ward[idx].patientName, ward[idx].age,
           ward[idx].disease, ward[idx].doctor);
}
โš ๏ธ findFreeBed() vs findBedIndex(). These solve two different problems โ€” one searches by a specific bed number the user typed, the other scans for the first available bed automatically. Mixing them up is an easy bug: always admit into the *first free* bed, never a bed number the user guessed.
part 3
3

Discharge Billing & File Saving

Two-part billing + persistence

Discharge billing has two components โ€” room charge and doctor fee โ€” both scaled by the number of days admitted. saveToFile() writes every bed as a CSV line, exactly like the Hotel and Library projects.

Part 3 ยท hospital.c โ€” discharge & file I/O
hospital.c
C
void dischargePatient() {
    int bedNo, days;
    printf("Enter bed number to discharge: ");
    scanf("%d", &bedNo);

    int idx = findBedIndex(bedNo);
    if (idx == -1) { printf("Bed not found.\n"); return; }
    if (!ward[idx].isOccupied) { printf("Bed is already free.\n"); return; }

    printf("Enter number of days admitted: ");
    scanf("%d", &days);

    float roomCharge   = days * ROOM_CHARGE_PER_DAY;
    float doctorCharge = days * DOCTOR_FEE_PER_DAY;
    float total        = roomCharge + doctorCharge;

    printf("\n----- Discharge Bill -----\n");
    printf("Patient : %s\n", ward[idx].patientName);
    printf("Doctor  : Dr. %s\n", ward[idx].doctor);
    printf("Days admitted: %d\n", days);
    printf("Room charge  : %d x Rs %.2f = Rs %.2f\n", days, (float)ROOM_CHARGE_PER_DAY, roomCharge);
    printf("Doctor fee   : %d x Rs %.2f = Rs %.2f\n", days, (float)DOCTOR_FEE_PER_DAY, doctorCharge);
    printf("Total Bill   : Rs %.2f\n", total);

    // free the bed for the next patient
    ward[idx].isOccupied = 0;
    strcpy(ward[idx].patientName, "-");
    ward[idx].age = 0;
    strcpy(ward[idx].disease, "-");
    strcpy(ward[idx].doctor, "-");
    ward[idx].daysAdmitted = 0;
}

void saveToFile() {
    FILE *fp = fopen("hospital_data.txt", "w");
    if (!fp) { printf("Error saving file.\n"); return; }

    for (int i = 0; i < TOTAL_BEDS; i++) {
        fprintf(fp, "%d,%d,%s,%d,%s,%s\n",
                ward[i].bedNo, ward[i].isOccupied, ward[i].patientName,
                ward[i].age, ward[i].disease, ward[i].doctor);
    }
    fclose(fp);
    printf("Data saved to hospital_data.txt\n");
}
๐Ÿ’ก Two rates, one total. Splitting the bill into roomCharge and doctorCharge before adding them isn't just for the printout โ€” it means adding a third charge type later (medicine, tests) is just one more line, not a rewrite.
part 4
4

The Main Menu

do-while + switch

Same shape as the Hotel and Library projects: a thin main(), a do-while loop, and a switch that routes to the right function. Once you've built this pattern once, every menu-driven C project follows it.

Part 4 ยท hospital.c โ€” main()
hospital.c
C
int main() {
    initWard();
    int choice;

    do {
        printf("\n===== HOSPITAL MANAGEMENT SYSTEM =====\n");
        printf("1. Display Ward Status\n");
        printf("2. Admit a Patient\n");
        printf("3. Discharge a Patient\n");
        printf("4. Search Patient by Bed\n");
        printf("5. Save Data to File\n");
        printf("6. Exit\n");
        printf("Enter choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: displayWard();       break;
            case 2: admitPatient();      break;
            case 3: dischargePatient();  break;
            case 4: searchPatient();     break;
            case 5: saveToFile();        break;
            case 6: printf("Exiting... Take care!\n"); break;
            default: printf("Invalid choice.\n");
        }
    } while (choice != 6);

    return 0;
}
terminal โ€” sample session
output
===== HOSPITAL MANAGEMENT SYSTEM =====
1. Display Ward Status
2. Admit a Patient
3. Discharge a Patient
4. Search Patient by Bed
5. Save Data to File
6. Exit
Enter choice: 1

Bed   Status     Patient            Age   Disease        Doctor
1     Free       -                  0     -              -
2     Free       -                  0     -              -
3     Free       -                  0     -              -
4     Free       -                  0     -              -
5     Free       -                  0     -              -

Enter choice: 2
Enter patient name: Meera Nair
Enter age: 34
Enter disease/reason for admission: Fracture
Enter assigned doctor's name: Dr. Anil Shah

Patient Meera Nair admitted to Bed 1 under Dr. Dr. Anil Shah.

Enter choice: 3
Enter bed number to discharge: 1
Enter number of days admitted: 4

----- Discharge Bill -----
Patient : Meera Nair
Doctor  : Dr. Dr. Anil Shah
Days admitted: 4
Room charge  : 4 x Rs 800.00 = Rs 3200.00
Doctor fee   : 4 x Rs 500.00 = Rs 2000.00
Total Bill   : Rs 5200.00

Enter choice: 6
Exiting... Take care!
โš ๏ธ Watch double "Dr." in output. The sample run typed "Dr. Anil Shah" as input while the code also prints its own "Dr." prefix โ€” a small but realistic bug. Either drop the printf's "Dr." prefix or tell users to enter the name without a title.
extend it
๏ผ‹

Ways to Extend This Project

Once the base version compiles and runs, these upgrades each reuse a concept from earlier lessons:

  • Load from file on startup โ€” read hospital_data.txt with fscanf so ward state survives between runs
  • Dynamic bed count โ€” replace the fixed array with malloc-allocated memory sized from user input
  • Appointment queue โ€” a queue of patients waiting for the next free bed
  • Doctor-wise patient list โ€” search/filter patients by assigned doctor using strcmp
  • Sort ward by days admitted โ€” plug in any algorithm from the Sorting lesson to flag long-stay patients
  • Medicine/test charges โ€” extend the billing struct with itemized charges beyond room + doctor fee
ExtensionConcept it reuses
Persistent load/saveFile I/O lesson
Dynamic bed countDynamic memory (malloc/realloc) lesson
Appointment queueStacks & Queues lesson
Sort by days admittedSorting Algorithms lesson
โœ“

Project Checklist

  • I understand the Bed struct and what each field stores
  • I can explain the difference between findBedIndex() and findFreeBed()
  • I can trace admitPatient() end to end
  • I understand the two-part billing (room charge + doctor fee) in dischargePatient()
  • I know why the bed is reset after discharge
  • I understand how saveToFile() writes each bed as a CSV line
  • I can trace the do-while + switch main menu loop
  • I compiled and ran the full program myself
  • I picked at least one extension to try next