TLDR; In this article we will at how you can work with the file system which will involves reading and writing to files.
Series:
The full series
- Your first program
- Variables
- Working with input and output
- Functions
- Control flow
- Working with files, you are here
- Pointers
- Error management
- Structs and Classes
Resources
Files
Your operating system is full of files, both files that you create and other files that belong to the operating system that you shouldn't touch. Many applications out there rely on files and the ability to create files for logging purposes for example or various reports. Additionally, being able to read from files is an important thing to be able to do.
Fstream library
In C++ you have a standard library called fstream
that allows you to work with the file system. It exposes three important classes that you should know about:
-
ofstream
. With an instance of this class you can create and write to files. -
ifstream
. This library enables you to read to files. -
fstream
. Sometimes you need the capability to both read and write, for that, you havefstream
, capable of doing both.
Reading
Let's start with reading from a file. You use ifstream
and create an object instance for it like so:
ifstream readstream("file.txt");
As you can see from the code, also specify a string that represents the full path to the file, including its file name.
At this point, you have reference to the file and is ready to read from it. So how do you read from it?
You use getline()
in combination with a while
loop to read each row from the file, line by line, like so:
string line;
while(getline(readstream, line))
{
cout << line;
}
readstream.close();
getline()
will return false
when there's no more to be read in the stream. Note how close()
is called as the last thing we do. It's important to close a stream or you might actually lock access for other code to access the file when you are done with it.
Check if we can read
So far, we've been very optimistic, we assume the file exist and we have the rights to read from it as well. However, you might be in a situation where the file doesn't exist, or you don't have rights to read from it. For that reason, you need to check whether the file is ready to be read from. Here's some code that checks that:
bool can_read(string filename)
{
ifstream readstream;
readstream.open(filename);
bool exists = false;
// is_open
if (readstream)
{
exists = true;
}
readstream.close();
return exists;
}
What's going on is that we call readstream.open()
, if we can read from this stream, then we are good to go. There are two ways to check its status, either as pictured above:
readstream.open("path/to/file/file.txt");
if(readstream)
{
// all is well
}
or you can use:
readstream.is_open()
which returns a boolean, true
if you can read from it, and false
, if you can't.
Worth noting is that it's hard to differ between cases such as that a file doesn't exist, and you don't have permission to read from it.
Reading a few characters
So far, you've seen how you read file content, line by line, you can also read a few characters or bytes at a time and more. Dealing with files is a really big topic, but let's show how you read a few characters:
char array [5];
ifstream read("file.txt");
read.read(array,5);
This code will instruct the ifstream
, instance to read 5 characters from the stream and place it in the array
variable.
Writing to a file
To write to a file, we need an instance of ostream
and the name of the file, like so:
ostream write("new_file.txt");
ostream << "line1\n";
ostream << "line2";
ostream.close();
The above code will create the file new_file.txt and two rows of text and then close the stream, which is important when you write to it as well. If this file already exists, its content will be replaced, so a heads up. What if you just want to add content to an existing file?
Append
Sometimes you just want to add content, and to do that, you need a slightly altered way of calling the code.
ostream writestream;
writestream.open("new_file.txt", ios_base::app);
writestream << "add this last";
writestream.close();
Note how we use the method open()
. Said method allows us to specify filename, as well as how to treat the file. The default with a writestream
is to attempt to create the file and replace what's there if it already exists. What we are doing is providing ios_base::app
, which is an instruction that says append, i.e. add the content to the end of the file.
Summary
In this article, we've learned how to work with files, reading and writing to them. Hopefully, you know have enough knowledge to learn to use files as part of your apps.
Top comments (0)