I've just started wondering - how is actually std::fstream
opened with both std::ios::in
and std::ios::out
actually supposed to work? What should it do? Write something to (for example) an empty file, then read... what? Just written value? Where would the file "pointer"/"cursor" be? Maybe the answer's already out there but I just couldn't have found it.
In order to use the C++ fstream, an object from the class has to be instantiated. The stream object then has to be opened for input or output or both. To append text to the file, the stream has to be opened for appending. Make a habit of always closing the stream after it has been opened and used.
std::fstream Input/output stream class to operate on files. Objects of this class maintain a filebuf object as their internal stream buffer, which performs input/output operations on the file they are associated with (if any). File streams are associated with files either on construction, or by calling member open .
fstream inherits from iostream , which inherits from both istream and stream . Generally ofstream only supports output operations (i.e. textfile << "hello"), while fstream supports both output and input operations but depending on the flags given when opening the file.
fstream is a proper RAII object, it does close automatically at the end of the scope, and there is absolutely no need whatsoever to call close manually when closing at the end of the scope is sufficient. In particular, it's not a “best practice” and it's not necessary to flush the output.
std::fstream
?std::fstream
is a bidirectional file stream class. That is, it provides an interface for both input and output for files. It is commonly used when a user needs to read from and write to the same external sequence.
When instantiating a bidirectional file stream (unlike std::ofstream
or std::ifstream
), the openmodes ios_base::in
and ios_base::out
are specified by default. This means that this:
std::fstream f("test.txt", std::ios_base::in | std::ios_base::out);
is the same as
std::fstream f("test.txt");
One would specify both options if they needed to also add some non-default openmodes such as trunc
, ate
, app
, or binary
. The ios_base::trunc
openmode is needed if you intend to create a new file for bidirectional I/O, because the ios_base::in
openmode disables the creation of a new file.
Bidirectional I/O is the utilization of a bidirectional stream for both input and output. In IOStreams, the standard streams maintain their character sequences in a buffer where it serves as a source or sink for data. For output streams, there is a "put" area (the buffer that holds characters for output). Likewise, for input streams, there is the "get" area.
In the case of std::fstream
(a class for both input and output), it holds a joint file buffer representing both the get and put area respectively. The position indicator that marks the current position in the file is affected by both input and output operations. As such, in order to perform I/O correctly on a bidirectional stream, there are certain rules you must follow:
This only refers to std::fstream
. The above rules are not needed for std::stringstream
.
I hope these answer your questions. If you have any more, you can just ask in the comments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With