Module 1 — Lab 1: the procedural baseline¶
Levels: [L2 Apply → L4 Analyze] · Extends: nothing — this is the first lab · Time: 2–3 hours
The scenario¶
A campus library has asked for a small lending desk program. An assistant must be able to add an item, lend it, take it back, and print the catalogue. The library is small — a few dozen items at most — and the request arrives with no hint that it will ever grow.
You are going to build it the clumsy way, on purpose: parallel arrays, global data, free functions. Not because it is good, but because in fifteen weeks' time you will be expected to explain what is wrong with it, and that is much easier from experience than from a lecture.
★ The clumsiness is the point. This lab is the "before" photograph in a before-and-after pair. If your version is messy, you have done it correctly. The lab brief says so explicitly because otherwise students tidy it up, delete the evidence, and lose the only thing the lab was for.
What you start from¶
Nothing. A blank file. This is the last lab in the course where that is true — from Lab 2 onwards you extend the previous lab's program.
Your program reads commands from standard input, one per line, so a session can be scripted and re-run:
| Command | Meaning |
|---|---|
A <id> <title> |
add an item with that identifier and title |
L <id> |
lend it |
R <id> |
take it back |
P |
print the catalogue |
Q |
quit (or just end the input) |
The reference solution is at examples/labs/lab-01/solution/main.cpp (verified to
build and run). Attempt the lab before reading it.
Requirements¶
- Three parallel arrays — identifiers, titles, and an on-loan flag — plus a count. Global, deliberately.
- A menu loop reading the commands above, with a sensible response for an unknown command.
- Add, search, lend, return, print as free functions. Each must take the arrays or the count it needs.
- At least one operation that can fail for two different reasons, returning the same result for both. Yes, deliberately — you will diagnose it in the reflection.
- Add a
publicationYearfield, and record how many places had to change. - Builds with no warnings using the course's one command:
g++ -std=c++17 -Wall -Wextra main.cpp -o library - A written reflection, no more than one page, answering the four questions under What to deliver.
What to deliver¶
The working program, plus a reflection of three short paragraphs covering:
- What hurt. The specific thing that annoyed you most while making requirement 5's change, with the number of lines you touched.
- What would break next. Add a fourth array — say, a borrower's name — and say which functions would need to change and which could silently go wrong.
- Where the rules live. Name three rules your program relies on (for example, "an item is available or on loan, never both") and, for each, where it is enforced: one function, several, or the writer's memory.
- The deliberate flaw. Requirement 4 asked for an operation that reports two different failures identically. Say which one it is, and what a caller would have to do to tell them apart.
Self-assessment checklist¶
Run it honestly. There is no marker in self-study, and this is the checklist a marker would use.
It builds and runs
- [ ] Compiles with
g++ -std=c++17 -Wall -Wextrawith no warnings - [ ] All five commands work as described
- [ ] An unknown command produces a message, not a crash
It is correct
- [ ] Lending an item that is already out is refused, and the catalogue is unchanged
- [ ] Returning an item that is not out is refused
- [ ] Boundary cases work: an empty catalogue, one item, a duplicate identifier
- [ ] Printing after each operation shows the state you expect
It is deliberately clumsy (this is a grading criterion, not a defect)
- [ ] The data really is in parallel global arrays, not tidied into a
struct - [ ] The free functions really do take the arrays or the count they need
- [ ] At least one operation really does conflate two failures
It is explained
- [ ] The reflection answers all four questions with specific numbers or lines
- [ ] You can say, out loud, what you would have to change first if items could be deleted as well as added
Common ways this lab goes wrong¶
| Symptom | Cause | Fix |
|---|---|---|
| The program reads no commands and exits | Input is being read with >> on a stream that has ended, or getline after >> left a newline |
Read whole lines with std::getline, then parse each line with an std::istringstream |
The title is empty after A 1001 C++ Primer |
Reading the title with >> stops at the first space |
Read the remainder of the line with std::getline and strip one leading space |
| Titles and identifiers drift apart | One array updated without the others | That is the lesson. Note the line in your reflection rather than fixing it silently |
| Duplicate identifiers accepted | No check on add | Search before inserting, and refuse — but keep the refusal crude, as Lab 1 requires |
| The reflection lists no numbers | The change was made without counting | Re-do requirement 5 on a copy of the file and count the changed lines with diff |
Reference solution¶
examples/labs/lab-01/solution/main.cpp
Read it after your own version builds and runs. It is not better than yours in
any way that matters for this lab — it is a comparison, and the differences are the
interesting part. In particular, it demonstrates the std::getline +
std::istringstream pattern that Lab 2 also uses, and its final comment lists the six
places a new field touches.
Next: Challenge problems — paper-only design work, and the bridge into Module 2.