Fstream File Input and Output in C++
Dr. Lawlor, CS
202, CS, UAF
First, I need to say a little about how files work in NetRun.
They don't.
That is, you can't (currently) do any of these in NetRun:
- Write files for your program to read.
- Read files that your program has written.
Sorry. What you can do, though:
- Write files as your program is running.
- Read those same files back into your program.
I've written a tiny utility function for NetRun called "cat(filename);" (from the UNIX utility named cat)
that reads and displays the contents of the file you give it. It
will tell you the length of the file too, and give you an error message
if the file does not exist.
Here I create a file with some simple data in it, and print the file:
fstream f;
f.open("ted",ios::out); // make a file "ted"
f<<"Excellent!\n"; // write some data to it
f.close(); // be sure to close it afterwards!
cat("ted");
(Try this in NetRun now!)
(Note: it is important to close the file before calling cat. If
the file is still open, "f" may have cached some of your output in its
internal buffers, and "cat" will tell you the file is empty.)
Here I'm trying to print a file that doesn't exist:
cat("totallythere");
(Try this in NetRun now!)
Here I'm printing out the binary executable "code.exe" (or at least the first 1000 bytes) :
cat("code.exe");
(Try this in NetRun now!)
Operations on an fstream
Here's a non-exhaustive list of what you can do with an fstream object:
- f.open(fileName,accessMode);
Access a file on disk. Depending on accessMode (see below), this
might create the file, or only be happy if the file already exists.
- f<<s; Write an object (string, int, and so on) to a file.
- f>>s; Read an object from a file.
- if (f) ...; Check if the file is "happy":
that no errors have occurred. An fstream may be unhappy because
you couldn't open the file, or you hit the end of the file, or the file
didn't contain the object you tried to read, or because your disk was
too full to write the object, and so on.
- f.clear(); Make a file be happy again after an error.
- f.close();
Stop accessing a file on disk. Note that close flushes any
buffered data, so all your output will actually end up in the
file. Leaving off "close" is a common error!
- f.flush(); Write any buffered data to the file, but leave the file open for access.
- f.seekp(0); Jump the write ("put") pointer back to the start of the file, so you can write a new copy of the file.
- f.seekg(0); Jump the read ("get") pointer back to the start of the file, so you can read it over again.
The possible access modes are:
- ios::in Open an existing file for reading.
- ios::out Create a file for writing, but do not change what is already in the file.
- ios::app Append the file.
Subsequent writes will jump to the end of the file. Typically
combined with ios::out, like "ios::out|ios::app". (Try this in NetRun now!)
- ios::ate Open the file and
seek to the end. This is similar to but slightly less reliable
than ios::app, and it only seems to work right when combined with
"ios::in|ios::out|ios::ate". (Try this in NetRun now!)
- ios::trunc Truncate any existing data in
the file while opening. Plain "ios::out" does this already, but
"ios::in|ios::out|ios::trunc" creates an empty file in fresh read/write
mode.
- ios::binary Access the file in binary mode (discussed next lecture).
For example, here we're writing some string data, and then reading some of it back in:
fstream f,g;
f.open("ted",ios::out); // make a file "ted"
f<<"Party on!\n"; // write some data to it
f.close(); // be sure to close it afterwards!
g.open("ted",ios::in); // reopen file
std::string s;
g>>s;
if (g) cout<<"Read from file: '"<<s<<"'\n";
else cout<<"Couldn't read from file...\n";
g.close();
cat("ted");
(Try this in NetRun now!)