C++ Parking Lot Management Project
Check vehicles in and out, assign spots, and bill by the hour.
What you will build
Run a car park: vehicles check in and get the nearest free spot, check out and pay for their stay. It blends resource allocation (which spot?), time arithmetic (how long?), and money (how much?) — three everyday programming concerns in one tidy system.
What you will learn
- Allocating and freeing resources from a pool
- Time arithmetic with std::chrono
- Tiered billing rules
- Occupancy reporting
Feature checklist
- Floors and numbered spots
- Check-in assigns the first free spot
- Check-out computes fee from duration
- Rates: first hour flat, then per hour, daily cap
- Live occupancy: free vs taken spots
- Ticket shows plate, spot, entry time
Starter code
#include <iostream>
#include <vector>
#include <string>
#include <chrono>
struct Spot {
bool taken = false;
std::string plate;
std::chrono::steady_clock::time_point in;
};
class CarPark {
std::vector<Spot> spots_;
public:
explicit CarPark(int n) : spots_(n) {}
int checkIn(const std::string& plate) {
for (size_t i = 0; i < spots_.size(); ++i)
if (!spots_[i].taken) {
spots_[i] = {true, plate, std::chrono::steady_clock::now()};
return (int)i + 1; // spot number
}
return -1; // full
}
double checkOut(int spotNo) {
Spot& s = spots_[spotNo - 1];
if (!s.taken) return -1;
auto hrs = std::chrono::duration_cast<std::chrono::hours>(
std::chrono::steady_clock::now() - s.in).count();
s.taken = false; s.plate.clear();
double fee = (hrs <= 1) ? 3.0 : 3.0 + (hrs - 1) * 2.0;
return fee > 20.0 ? 20.0 : fee; // daily cap
}
};Full walkthrough
Step 1: Model spots and let CarPark own them
struct Spot { int floor, number; bool occupied; std::string plate; time point of entry } and class CarPark holding a vector of Spots, built from floors × spots-per-floor. Occupancy lives ON the spot; the 'first free spot' is a search, not a separate list that can disagree with reality.
Step 2: checkIn(): assign the first free spot
Linear-scan the spots for the first !occupied, mark it with the plate and the current time from std::chrono::steady_clock (or store a system_clock time to print), and issue the ticket: plate, spot id (F1-07 style = floor 1, spot 7), entry time. First-free assignment keeps cars packed near the entrance and the algorithm obvious.
Step 3: checkOut(): find by plate, price the stay
Find the occupied spot with this plate, take the exit time, and compute the duration. Free the spot (occupied = false, clear the plate). Finding by plate — not by ticket number — is what the driver at the barrier actually has, so the API follows the human.
auto hrs = std::chrono::duration_cast<std::chrono::hours>(out - in);
// fee from hrs and the leftover minutes, per the tariff belowStep 4: Implement the tariff exactly as specified
First hour flat 500; each additional STARTED hour +200; the whole thing capped at 2000 per day. 'Started hour' means ceiling division: 3h12m bills as the first hour plus 3 additional = 500 + 3×200 = 1100. Tariff bugs are money bugs — write the fee as a small pure function feeFor(duration) you can unit-test on paper: 45m → 500, 60m → 500, 61m → 700, 10h → 2000 (cap).
Step 5: Show live occupancy
Count free vs taken spots overall and per floor by scanning the vector. Derived, as always — the count cannot drift from the spots because it IS the spots, counted.
Step 6: Persist the car park
Save occupied spots (spot id, plate, entry timestamp) to a file on each check-in/out and reload at startup. Timestamps must be system_clock here (steady_clock points are meaningless after a restart — a subtle and genuinely important distinction this project teaches by accident).
Step 7: Test the money story
Check in two cars, check one out within the hour (500), simulate a 3h12m stay (1100) by temporarily back-dating an entry during testing, fill the lot completely and confirm the next check-in gets a graceful 'Lot full', and restart mid-stay to prove persistence kept the entry time.
Common mistakes
- Storing entry times as steady_clock points and persisting them — after a restart those values are meaningless; persist wall-clock times.
- Rounding duration DOWN to whole hours, undercharging every stay and failing the 'started hour' rule.
- Freeing the spot before computing the fee, losing the entry time the fee depends on.
Compile and run
g++ -std=c++17 -o parking parking.cppSample run
$ ./parking
1) Check in 2) Check out 3) Occupancy 0) Exit
> 1
Plate:
> ABC-123
Ticket: ABC-123 -> Spot F1-07, entered 09:12
1) Check in 2) Check out 3) Occupancy 0) Exit
> 1
Plate:
> XYZ-789
Ticket: XYZ-789 -> Spot F1-08, entered 09:15
> 3
Floor 1: 8/40 taken · Floor 2: 0/40 taken · Total free: 72
> 2
> ABC-123
ABC-123 at F1-07: entered 09:12, leaving 12:24 (3h 12m)
Fee: first hour 500 + 3 extra hours x 200 = 1100
Spot F1-07 is now free.
> 0Try it in your browser
No browser demo is included for this project. Build the C++ version below — that is the real program.