UPI Study › Courses › C++ Programming › Free lessons › Lesson 10.4 Free with a free account
Applied Challenge: File Operation Exercises
C++ Programming · Chapter 10: File Access and MemorySection 10.4 · lesson 72 of 84video coming soon
← Designing a File-Driven Record SystemNext lesson: Pointers →
In this lesson
End-to-end drills, failure paths included.
- Apply 3 checks to every file operation
- Copy, count, merge and filter files
- Append to a log, and degrade gracefully
- Test against a file-handling checklist
Transcript
Everything said in the video, section by section (1,655 words). Read along, or search it.
Lesson Overview
Seven Drills and Their Failure Paths
Seven small programs, each doing one thing with files. None of them is difficult. What makes them worth writing is the second half of each drill: the path where the file is missing, unreadable, empty, or not shaped the way you assumed. That path is where file-handling code is actually judged, and it's the part most beginners leave out. For each drill, write it, read the solution, then make its failure cases happen deliberately, and check what yours does.
Core Idea
Files Live Outside Your Program
A file lives outside your program. It may not exist, it may be unreadable, it may vanish while you're working on it, or contain something quite different from what you expected. None of that is exceptional. It's the ordinary condition of working with files. So three checks apply to every file operation.
Three Checks
Open, Read, and Write Verification
Did it open? Testing the stream catches a missing file, a wrong path, or no permission. Did each read succeed? Get line in the loop condition catches the end of file, and any error part way through. And did the writing get out? Testing the stream after writing catches a full disk or a lost device, problems that only appear once data is actually flushed.
Deep Dive
Why Getline Belongs in the Loop
The second check deserves a sentence of its own. Putting get line in the loop condition isn't merely tidy. It is the check. The call reports whether it produced a line, so the loop ends on end of file and on error, and nothing is processed that was never read. Streams close themselves when they go out of scope, so an explicit close is usually unnecessary. Call it when you need the data on disk before the function ends, for instance because you're about to read the same file back. And check the stream afterward, since that's the moment a write failure finally becomes visible.
Drill One
Copying a File Line by Line
Drill one: copy a text file, line by line, and report clearly if either file can't be opened. Open the source first, and stop if it can't be read. Then open the destination, and stop if it can't be written. Copy each line, close the output, and check it, because a write failure surfaces there. The order matters. If the source doesn't exist, don't create the destination. An empty output file is worse than none, because it looks like a successful copy. If the source and destination are the same file, opening the output truncates it, destroying the source before it's read. Compare the paths, and refuse. An empty source produces an empty copy, which is correct. And a last line with no newline gains one, which is acceptable for text, though the copy is no longer byte-identical.
Drill Two
Counting Lines, Words, and Characters
Drill two: report the number of lines, words and characters in a file, in a single pass. Each line counts as one, and its characters plus one for the newline get line removed. Words are counted by transition, not by separator. A word is counted at the moment you step from a separator onto a non-separator. Counting separators instead gives the wrong answer for leading spaces, trailing spaces and doubled spaces, all common, and none of them errors. Tabs are handled because they're tested for explicitly. The sample file has four lines and seven words, thirty-seven characters. And an empty file reports zero, zero, zero. That's a result, not a failure, so don't print an error.
Drill Three
Merging Two Sorted Files
Drill three: two files each hold sorted lines. Produce one sorted file containing everything from both. The trick is that neither file needs to be read into memory. Hold one line from each, write whichever comes first, and replace only that one. Apple and berry are held. Apple is smaller, so it's written, and file A supplies mango. Then berry is written, and file B supplies fig. And so on. Neither file is ever fully in memory, so this works on files far larger than the machine could hold. When either side runs out, two more loops drain whatever remains in the other.
Common Mistake
Forgetting the Drain Loops
Those two drain loops after the main one aren't optional. When one file runs out, the other almost always has lines left. Omit the drain loops, and they're silently discarded. And the output still looks sorted, which is exactly what makes the bug hard to notice. Test with files of clearly different lengths, in both orders. Notice also less-than-or-equal in the comparison. Less-than would still sort correctly, but less-than-or-equal sends ties to A first, so equal lines keep the order of the inputs. When records rather than words are being merged, that stability matters.
Quick Check
Merging Without Drain Loops
Quick check. Leave out the two drain loops, and merge a file holding apple, mango and pear with one holding berry and fig. What ends up in the merged file? Pause and think. Just apple, berry and fig. When file B runs out, mango and pear are still waiting in A, and nothing writes them. The output is sorted, and incomplete.
Drill Four
Filtering Records and Counting Skips
Drill four: a file holds records as roll, name, course and marks, separated by bars. Write out only those on a given course, and report how many lines were unusable. Blank lines are skipped, because they aren't errors. Each other line is split at the bars. If it doesn't have exactly four fields, it's malformed, so count it and move on. If the course matches, write the line and count it. At the end, report how many matched, and how many were skipped. That skip count is the whole point of the drill. Silently dropping bad lines and silently dropping none look identical from outside, so a program that never mentions them can't be trusted to have found any. One integer turns invisible data loss into a number someone can act on.
Drill Five
Appending Timestamped Log Lines
Drill five: add a line to a log file without disturbing what's already there. Open the stream in append mode. Stop if it didn't open. Format the current time as a timestamp, write it with the message, close, and return whether the stream is still good. The output adds timestamped lines: roster loaded, a record added, a save that failed. The mode flag is the entire drill. Opening a file for output truncates it by default. The previous contents are gone before you write a single byte. For a log, that's the difference between a record of what happened, and a record of the last thing that happened. It destroys data, rather than merely failing to produce it.
Drill Six
Loading Settings: Absent Versus Unreadable
Drill six: load settings from a file. Missing is normal. Unreadable isn't. Behave differently. Programs routinely treat both as one case, reporting a scary error on the first run, or saying nothing when a real problem occurs. If the stream never opened, the result is absent. If it opened, every line is applied, and afterward, a bad stream means it failed part way: unreadable. Otherwise, loaded. The distinction is fail against bad. Reaching the end of a file is an ordinary stop. A genuine read error sets the bad condition.
Handling Outcomes
Responding to Absent, Unreadable, Loaded
Absent means use defaults, mention it once quietly, and carry on. On a first run, that's expected. Unreadable is a real problem. Warn prominently, and don't save over the file. Partial data plus a save is how files get destroyed. And loaded means everything was read, so carry on.
Drill Seven
Finding the First Differing Line
Drill seven: report whether two files are identical, and if not, the first line at which they differ. Each pass reads a line from both files, and counts the line number. If neither got a line, both ended together: the files are identical. If only one did, one file ends at this line. And if both did but the lines differ, they differ here. Both files must be read on every pass, even when the first already reports its end. Otherwise the streams fall out of step, and a shorter file is reported as matching. And the three checks must come in this order. Reorder them, and the program is right on most inputs, and wrong on the ones that matter.
Checklist
Testing Every File-Handling Program
Here's a checklist to test every file-handling program against. A file that doesn't exist, or can't be accessed, leaves the stream false right after opening. Report the path, and decide deliberately whether that's normal or fatal. A file that opened, then failed mid-read, shows bad after the loop. Treat the data as incomplete, and never write it back over the source. A write that failed shows false after close. Warn loudly: the user believes the work is saved. An empty file usually means a valid result. A malformed line should be skipped, counted, and reported. Output opened over the input must be refused. Every output open should be reviewed for a missing append flag. And a very large file should be streamed a line at a time, never loaded whole.
Further Practice
Extra Drills and Failure Paths
A few further drills extend these. Copy a file, skipping blank lines, and report how many. Count how often each line length occurs, as a histogram. Merge three sorted files at once. Harder: split a large file into numbered parts of at most N lines. Report every line in one sorted file, but absent from another. Detect whether a file is actually sorted, and where it isn't. For each one, write the failure paths down before you write the code. If you can't name three, you haven't looked hard enough at what the file might do to you.
Quick Check
Comparing Files of Unequal Length
Here's something to think about. One file holds three lines. Another holds the same three lines, and then a fourth. What does the compare drill print? Pause and think. One ends at line four. The first three passes match. On the fourth, only one file produced a line, so the second check fires before the contents are ever compared.
Key Takeaways
Summary of File Handling Habits
To summarize. Check that the file opened, that every read succeeded, and that the write got out. Open the source before the destination, and drain both inputs when merging. Count and report what you skip. Append to logs, and never save over a half-read file.
About C++ Programming at UPI Study
C++ Programming (Computer Science 242) is a self-paced online course of 84 video lessons in 11 chapters, from your first program to decisions, loops, arrays, functions, classes, files, pointers and inheritance. It carries a NCCRS credit recommendation for 3 semester credits.
Every lesson transcript is free on pages like this one, and the videos are free with a free UPI Study account. Enrolling adds a practice quiz after each lesson, the graded work and final exam that earn the credit, lifetime access, and an official transcript on completion. UPI Study has helped over 130,000 students with college credits. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
Enroll now → Course details Download the syllabus Every course with PRO →
Why take it here
Why students take C++ Programming with UPI Study
Where the credit goes
Universities that work with NCCRS
C++ Programming carries a NCCRS credit recommendation. These universities work with NCCRS; some are UPI Study's signed partners. ACE and NCCRS have over 2,100 cooperating colleges that will consider accepting credits; the final decision is with the universities.
Thomas Edison State UniversitySigned partner
University of the PeopleSigned partner
Charter Oak State CollegeSigned partner
Strayer UniversitySigned partner
Columbia Southern UniversitySigned partner
Indiana TechSigned partner
Penn StateWorks with NCCRS
Southern New Hampshire UniversityWorks with NCCRS
SUNYWorks with NCCRS
+many more cooperating universitiesFind my college →Find my college → Not listed? Ask Athena in the corner of this page, or book a 15-minute call.
FAQ
Questions students ask us
About Applied Challenge: File Operation Exercises
What three checks should I apply to every file operation in C++?
Why should getline be in the while loop condition when reading a file?
Why does my merge of two sorted files lose lines at the end?
Why did opening a log file erase its old contents, and how do I append instead?
About the C++ Programming course
How many college credits is C++ Programming?
How much does C++ Programming cost and what is included?
Which universities accept UPI Study credits?
How long does C++ Programming take?
How are the exams done?
How do my credits reach my college?
Ready for the full course? Earn 3 credits in C++ Programming.
84 video lessons, a quiz after each one, and the graded work that earns the credit. Recommended for credit by NCCRS.
3 credits · NCCRSEnroll →