A file stream object keeps track of whether its last operations were successful. That memory is called the stream's state, and can be checked at any time. The same stream also takes flags that tell it how to open the underlying file; those flags are the open modes.
The constructed stream's state can be tested immediately after the construction.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream in{"data.txt"};
// Check this condition before entering the block
if (in.good())
std::cout << "stream is good\n";
else
std::cout << "stream is not good\n";
return 0;
}
The member function good returns true if none of the error flags are raised. If data.txt exists and opens successfully for reading, you'll see the message stream is good. If the file doesn't exist and the open fails, good returns false and the other message is output.
Another three member functions report the individual flags which make a stream not good. fail is true if a formatting or extraction error occurred, bad is true if a more serious hardware level failure occurred, and eof is true if the end of the file is reached.
#include <iostream>
#include <fstream>
int main()
{
// Open this file stream for reading
std::ifstream in{"missing.txt"};
std::cout << in.fail() << '\n';
std::cout << in.bad() << '\n';
std::cout << in.eof() << '\n';
return 0;
}
The file doesn't exist so the open sets the fail bit. The first insertion hence outputs 1. Both the bad bit and eof bit are zero, so the next two insertions output 0. The stream cannot be used for input anymore until the fail bit has been cleared.
The member clear clears all of the error flags and restores the stream to the good state.
#include <iostream>
#include <fstream>
int main()
{
std::ifstream in{"missing.txt"};
std::cout << in.fail() << '\n';
in.clear();
std::cout << in.fail() << '\n';
return 0;
}
After the open failed, the fail bit is set and the first insertion outputs 1. The call to in.clear() clears the bit. The second insertion outputs 0.
Clearing the state does not reopen the file.
It simply clears the saved error so that subsequent operations can be attempted.
Open modes are modes that can be set when constructing a stream or when calling the open member function on a stream. They determine whether a file is created, whether the existing contents of a file are discarded, and whether all output happens at the end of the file. The mode std::ios::out requests output and is supplied automatically by std::ofstream. If the mode std::ios::app is added, then it means that all output happens at the current end of the file:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
{
// Open this file stream for writing
std::ofstream out{"log.txt", std::ios::app};
out << "first\n";
}
{
std::ofstream out{"log.txt", std::ios::app};
out << "second\n";
}
std::ifstream in{"log.txt"};
std::string word;
while (in >> word)
std::cout << word << '\n';
return 0;
}
Every std::ofstream is opened with the append mode. The first block writes the word "first." The second one reopens the same file and writes the word "second" after the content already existing. When the file is read later, the two words are printed in the order they are written.
The mode std::ios::trunc does the reverse. Any current content will be replaced when the file is opened. This mode is the default for std::ofstream, so a second write without the app will replace the data written previously.
#include <iostream>
#include <fstream>
#include <string>
int main()
{
{
std::ofstream out{"log.txt"};
// Use the newline escape sequence inside this literal
out << "first\n";
}
{
std::ofstream out{"log.txt"};
out << "second\n";
}
std::ifstream in{"log.txt"};
std::string word;
while (in >> word)
std::cout << word << '\n';
return 0;
}
The second open with truncation in the file, leaving the word "second" in the file when opened again.
Modes can also be combined with the bitwise or operator. Opening a file for both reading and writing is written by:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
// Combine file open-mode flags with bitwise OR
std::fstream io{"data.txt", std::ios::in | std::ios::out | std::ios::trunc};
io << "hello\n";
io.seekg(0);
std::string word;
io >> word;
std::cout << word << '\n';
return 0;
}
The stream io is an std::fstream capable of insertion and extraction. The combined mode creates an empty file, the insertion inserts characters into it, seekg moves the read position back to the beginning, and the extraction retrieves the word that was just inserted. The last insertion outputs that word.
Stream state and open mode work in conjunction.
The mode specifies how the file is connected on open, the state keeps track of if those connections became successful after subsequent operations. It is by testing the state after each major operation and selecting the correct mode on the file open call that a program's file handling remains predictable and reliable.
0 comments
No comments yet. Be the first.