I\'m using a FileManager for a project so that reading and writing is less of a hassle for me. Or would be, if I didn\'t spend all this time debugging it. So, this comfort-c
Best method:
void FileManager::open(std::string const& filename)
{
using std::ios_base;
if( stream_.is_open() )
stream_.close();
stream_.open( filename.c_str() ); // ...try existing file
if( !stream_.is_open() ) // ...else, create new file...
stream_.open(filename.c_str(), ios_base::in | ios_base::out | ios_base::trunc);
}
So the code tests for an existing file and, if not, creates it.
Just get your function to open
void FileManager::open(std::string const& filename)
{
using std::ios_base;
if(stream_.is_open())
stream_.close();
stream_.open(filename.c_str(), ios_base::in | ios_base::out | ios_base::trunc);
}
if that is the mode you require.
There is no magic way to open a file for read/write creating it if it does not exist but not truncating it (removing its content) if it does. You have to do that in multiple steps.
How can I accomplish this?
std::ofstream file("file.txt");
file << data;
Isn't that simpler?
You have to call fstream::open
with an explicit openmode
argument of
ios_base::in | ios_base::out | ios_base::trunc
Otherwise open
will fail due to ENOENT
.
Table 95 of the draft C++ standard lists possible file open modes and their equivalent in stdio
. The default, ios_base::out | ios_base::in
is r+
. The one I listed above is equivalent to w+
. ios_base::out | ios_base::app
is equivalent to a
. All other combinations involving ios_base::app
are invalid.
(At the risk of being scoffed at: you could switch to stdio
and use the file mode a+
, which reads from the start and appends at the end.)
That's the way the library works: std::ios::in | std::ios::out
opens it in the equivalent of stdio
's "r+"
, that is it will only open an existing file. I don't believe there's a mode that will do what you are wanting, you'll have to us an OS-specific call or check the file for existence (again, using an OS-specific call) and open it in one mode or the other depending on whether it already exists.
Edit: I assumed that you didn't want the file truncated if it already exists. As other people have noted, if you're happy to truncate any existing file then in | out | trunc
is an option.
You cannot use std::ios::in
on a non-existing file. Use
std::ios::in | std::ios::out | std::ios::trunc
instead (but make sure it doesn't exist or it will be truncated to zero bytes).