UPI Study › Courses › C++ Programming › Free lessons › Lesson 9.8 Free with a free account
Opening Channels to Files
C++ Programming · Chapter 9: Structs, Classes, and File StreamsSection 9.8 · lesson 66 of 84video coming soon
← Tracking Down Class BugsNext lesson: File Read and Write Operations →
In this lesson
Stream objects and their purpose.
- Explain why console and file work share one interface
- Choose ifstream, ofstream or fstream; open and close
- Check is_open(), and choose an open mode safely
- Explain why a relative path can fail elsewhere
Transcript
Everything said in the video, section by section (1,431 words). Read along, or search it.
Opening Hook
Files Give Programs a Memory
Every program so far has forgotten everything the moment it ended. Files are how that stops being true. And the way C++ reaches them turns out to be something you already know. The object that writes to a file behaves exactly like the one that's been writing to your screen, all along. This lesson is about opening and closing that channel correctly. What travels through it comes next.
Core Idea
A Stream Hides Its Destination
A stream is an object standing for a place characters can flow to or from. That's the whole idea, and its power is in what it deliberately leaves out. A stream doesn't say what's at the other end. So the machinery you learned for the screen transfers unchanged. Sending a value into cout, and sending the same value into a file, use the same operator, the same formatting settings, and the same rules about buffering. Only the object differs. Here, one function takes any output stream. It writes to the screen, then to a file, and the file holds exactly the same line. Code written against the interface doesn't need to know which destination it has. That's abstraction doing real work. What you already know about output doesn't have to be learned again.
File Stream Types
Ifstream, Ofstream, and Fstream Compared
File streams live in a header of their own, fstream. Including it makes three types available, and choosing between them is a matter of stating the direction of travel. Ifstream reads only. It fails to open if the file doesn't exist. Use it when the file is a source of data your program must not damage. Ofstream writes only. It creates the file if absent, and empties it if present. Use it when you're producing a file, but see the open modes before using it on a file that matters. And fstream does either or both, depending entirely on the modes you give it. These are ordinary objects. They're created, they hold state, and they have a destructor that runs when they cease to exist. Nearly everything here follows from taking that seriously.
Opening Forms
Construct With a Name or Open Later
A file can be attached to a stream at the moment the object is created, by naming the file as a construction argument. Or the object can be created empty, attached to nothing, and attached later with open. Both forms produce the same result. Prefer the first. An object that's created already usable can't accidentally be used before it's ready. The second earns its place when the filename isn't known at the point of declaration, or when one stream object is used for several files in turn.
Closing
Three Reasons to Call Close
Close detaches the stream from the file, and the destructor calls it automatically when the object ceases to exist. So a program that never calls it isn't broken. But there are three reasons to write it anyway. It frees the file immediately, rather than at the end of a scope that might be long. An open file may be locked against other programs, and on some systems, output isn't fully committed until it's closed. It makes the stream reusable. A stream must be closed before it can be opened on another file, which is exactly when the second opening form is useful. And it states the intent. A reader sees where you considered the file finished with, rather than working out where the object goes out of scope.
Error Checking
Opening Fails Quietly, So Check
Opening a file can fail. And this is the most important sentence in the lesson: it fails quietly. So every open should be followed by a check. Is open answers whether the stream is actually attached to a file. If it isn't, report it, ask for another name, use a default, or stop. But don't carry on as though it opened. Run it on a file that doesn't exist: the program reports it, and stops. The causes are many. The file isn't there, often from a typo or the wrong working directory. Writing doesn't create missing folders. The file may exist without this program having permission. The name may be a folder, which can't be opened for writing. Or the stream may already have a file open.
Why It Matters
Silent Failures Send You Searching Wrongly
Here's why that check matters so much. The object is created, the statement completes, and nothing is reported. A program that skips the check doesn't crash. It runs, produces no output or empty results, and leaves the person using it to guess why. And because the file operation itself never complained, the search for the cause usually starts in the wrong place entirely. One if, after every open, removes an entire category of bewildering behavior.
Open Modes
Mode Flags and Combining Them
A mode says what the stream is for, and what should happen to a file that already exists. Each mode is a value from std ios. In opens for reading. The file must already exist. Out opens for writing, creating the file if it's absent, and on its own, it implies truncation. App, for append, preserves the contents, and sends everything written to the end. Trunc empties the file immediately on opening. Ate starts positioned at the end, but doesn't force later writing to stay there. It doesn't keep the contents by itself: with out alone, the file is still emptied, so pair it with in. And binary suppresses character translations, and is required for non-text files. Modes combine with a single vertical bar between them, which reads as and. Out bar app means write, keeping what's there.
Common Mistake
Opening for Output Destroys Data
Creating an ofstream without stating a mode means out and trunc. And truncation happens when the file is opened, not when something is written. So the default version, which contains no writing at all, empties an existing file just by opening and closing it. Take a file holding 34 bytes. Opened for reading, the file is untouched. Opened with the default output mode, it drops to zero bytes. Opened with out and app, it still holds 34. Nothing was written in any of the three. Opening for output is itself a destructive act. So when opening a file for output that might already exist, and might matter, state the mode explicitly. It takes a few seconds. Recovering a log file that a test run silently emptied doesn't.
Worked Example
Same Program, Different Working Directory
A filename with no folder in it is a relative path. It's resolved against the working directory: the folder the program was started from, which isn't necessarily the folder the program is stored in. That's easiest to see by running one program from two places. Started from its own folder, the relative name readings dot txt is found. That prints a 1. Started from the parent folder, the same relative name isn't found. That prints a 0. An absolute path would still work. Same program, same file, same disk. The only thing that changed is where the terminal was standing when the program started.
Path Types
Relative Versus Absolute Paths
So there are two kinds of path. A relative path is resolved against the working directory, wherever that happens to be. It suits files that travel with the program, and anything that must work on somebody else's machine. An absolute path names the location outright. It suits a fixed, known location, but it's rarely portable. Two things make paths harder than they look. Separators differ. Windows writes backslashes, which must be doubled inside a string literal. And where a program is run from isn't where it's stored. Development tools often start a program from the project folder, so it finds its file inside the tool, and fails from a terminal. If a relative path fails, print the working directory first.
The Pattern
Open, Verify, Use, Close
Everything assembles into a short pattern, worth writing the same way every time. One: open at construction, naming the file, and stating the mode if the default would destroy something. Two: verify with is open, and handle the failure. Don't continue as if it worked. Skip this, and you get silent wrong behavior. Three: use the stream, which is the next lesson. And four: close it explicitly when finished. Skip this, and it still works, but holds the file longer. Here is the pattern running: write, reopen, read back.
Quick Check
Why the Scores Disappeared
Quick check. To test that scores.txt exists, a program opens it with an ofstream, checks is_open, and closes it. Now the scores are gone. Why? Pause and think. The check destroyed the data. An ofstream with no mode means out and trunc, so opening it emptied the file. Test with an ifstream instead.
Key Takeaways
Stream Interface, Checks, and Default Truncation
To summarize. Files use the same stream interface as the screen. Ifstream reads, ofstream writes, and fstream does both. Opening fails quietly, so check is open every time. And ofstream's default mode empties an existing file the moment it opens. Relative paths depend on where the program was started.
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 Opening Channels to Files
Should I use ifstream, ofstream, or fstream in C++?
How do I check whether a file opened successfully in C++?
Why did opening a file with ofstream erase its contents?
Why does my C++ program find a file in my IDE but not from the terminal?
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 →