I was looking at the SO post C++ file stream open modes ambiguity. I wanted to know the default file opening mode of fstream. One of the answer says,
What the above implies is that the following code opens the file with
exactly the same open flags fstream f("a.txt", ios_base::in |
ios_base::out); ifstream g("a.txt", ios_base::out); ofstream
h("a.txt", ios_base::in);
So if I understand correctly, in case I create object of fstream, I should be able to either read or write.
But below code does not write any data to file
fstream testFile1;
testFile1.open("text1.txt");
testFile1<<"Writing data to file";
testFile1.close();
However adding mode as given below creates text file with data "Writing data to file"
testFile1.open("text1.txt", ios::out);
So whether the default mode is implementation defined? I am using TDM-GCC-64 toolchain.
The default mode for std::fstreams is std::ios::in|std::ios::out. (Source)
The reason your code doesn't print anything to test1.txt is that the std::ios::in|std::ios::out mode does not create the file if it does not already exist (Source: table on this page).
You can use the std::ios::in|std::ios::app mode, which will start reading from the start, will start writing from the end, and will create the file if it does not exist. Note that using app mode, the file will seek to the end before each write (Source).
The default mode of ifstream is in. The default mode of ofstream is out. That's why they're named that way. fstream has no default mode.
Your example only shows the two defaults, and it shows that by omission of explicit arguments. That fstream f("a.txt", ios_base::in | ios_base::out) uses two explicit arguments is precisely because there is no default mode.
Related
I have this strange bug. I have a program which writes text to the file using the fstream, but the file is not being created and therefore no text is appended. When I debug my code, it shows me this:
create_new_file = {_Filebuffer={_Pcvt=0x0000000000000000 <NULL> _Mychar=0 '\0' _Wrotesome=false ...} }.
But whenever I use ofstream everything works.
Here is the code:
std::fstream create_new_file{ fileName.str()};
std::unique_ptr<std::string> changes = std::make_unique<std::string>("");
std::cin >> *changes;
create_new_file << *changes << "\n";
Here is the code which works:
std::ofstream create_new_file{ fileName.str()};
I have seen a similar post on Stack Overflow but the answer did not resolve my issue. I have tried adding the std::ios::trunc to the fstream but that did not help. But whenever I use ofstream everything works just as expected.
The problem is that for bidirectional file streams the trunc flag must always be explicitly specified, i.e., if you want the file content to be discarded then you must write in | out | trunc as the second argument as shown below.
Thus, to solve the problem change std::fstream create_new_file{ fileName.str()}; to :
//-------------------------------------------------------------------------vvvvvvvvvvvvvvv---->explicitly use trunc
std::fstream create_new_file{ "output.txt", ios_base::in | ios_base::out | ios_base::trunc};
Working demo
This file stream buffer open reference is useful. It shows a table with the different modes and what happens when they are used.
When you open a std::fstream the default mode for the constructor is in | out. If we look that up in the table we see that this will fail if the file doesn't exist.
And you never check for failure (which you always should do).
If you only want to write to the file then use std::ofstream as it will open the files in out mode, which creates the file if it doesn't exist.
If you want to only append to the file, still use std::ofstream but use the mode out | app, which will create the file and make sure all output is appended (written to the end).
How could I make my own file extention that works on a raspberry pi from C++?
I would like to make a file extention that keeps information for a custom OS for mobile devices such as phones, and tablets. what would the proper way to code an extention for this? information as in names, DOB, maybe their contacts?, and basically anything on the phone that id need to be stored permanantly. how would I do that?
File extensions don't really mean anything, it's just a part of the the file's name. It helps tell the operating system to what program to run with the given file. So making a file extension is quite simple, you just write your data to a file. Here is a great example of doing it in C++
After you have your binary you can read back just as easily, I'll quote a few lines from this site
A file stream object can be opened in one of two ways. First, you can supply a file name along with an i/o mode parameter to the constructor when declaring an object:
ifstream myFile ("data.bin", ios::in | ios::binary);
Alternatively, after a file stream object has been declared, you can call its open method:
ofstream myFile;
...
myFile.open ("data2.bin", ios::out | ios::binary);
Either approach will work with an ifstream, an ofstream, or an fstream object.
Normally, when manipulating text files, one omits the second parameter (the i/o mode parameter). However, in order to manipulate binary files, you should always specify the i/o mode, including ios::binary as one of the mode flags. For read/write access to a file, use an fstream:
fstream myFile;
myFile.open ("data3.bin", ios::in | ios::out | ios::binary);
To read from an fstream or ifstream object, use the read method. This method takes two parameters:
istream& read(char*, int);
The read member function extracts a given number of bytes from the given stream, placing them into the memory pointed to by the first parameter. It is your responsibility to create and manage the memory where read will place its result, as well as to ensure that it is large enough to hold the number of bytes requested. The bytes that are read and not interpreted, the method does not assume anything about line endings, and the read method does not place a null terminator at the end of the bytes that are read in.
If an error occurs while reading (for example, if you read off the end of a file), the stream is placed in an error state. If that occurs, you can use the gcount method to find out the number of characters that were actually read, and use the clear method to reset the stream to a usable state. Once a stream goes into an error state, all future read operations will fail.
An example:
#include <fstream.h>
...
char buffer[100];
ifstream myFile ("data.bin", ios::in | ios::binary);
myFile.read (buffer, 100);
if (!myFile) {
// An error occurred!
// myFile.gcount() returns the number of bytes read.
// calling myFile.clear() will reset the stream state
// so it is usable again.
}
...
if (!myFile.read (buffer, 100)) {
// Same effect as above
}
Consider the following code snippet:
const char * filePath = "C:/blah.mtt";
fstream fs(filePath, ios::in | ios::out | ios::binary);
if (fs.fail())
std::cout << "Failed to open the file!\n";
the fs.fail() check succeeds always. Does it mean that I can't open a file in both read write mode at the same time?
Creating an empty file first and then running the above code, fs.fail() is false always. What is the rational for such a behavior by the fstream class?
Note: I do have requisite permissions for creating the file. I am trying this on windows 10 using VS2015
Does it mean that I can't open a file in both read write mode at the same time?
No, you can do this, but the question is whether you can create a file by doing so.
Generally you'll need to add the trunc flag (ironically one of the options for how to handle an existing file), or remove the in flag (see here).
Yes, this is a bit of a pain, but it comes from how the original POSIX APIs work. Blame them!
Creating an empty file first and then running the above code, fs.fail() is false always. What is the rational for such a behavior by the fstream class?
You can always open a file that exists (well, subject to permissions). That behaviour makes sense.
the fs.fail() check succeeds always. Does it mean that I can't open a file in both read write mode at the same time?
Refer to #Lightness Races in Orbit's answer for a better explanation.
Creating an empty file first and then running the above code, fs.fail() is false always. What is the rational for such a behavior by the fstream class?
If you look at the constructor definition of fstream you can see that mode defines the way you open it. It has other options like app to append to an existing file. If you open up a file using the following code:
fstream fs(filePath, ios::in | ios::out | ios::binary);
You are saying create a new file if it doesn't exist. Which fails if you pre-created it. You should add the app, ate or truncflag if you want it to open successfully. This depends on what exactly you want to do. However, do note that in between the steps of creating and then opening it doesn't guarantee that the file is still there. You should try to do it in one swoop and let exception handling do its work, since you can never go around the errors anyway.
I am developing in C++ using NetBeans 6.9 on Ubuntu 11.04. I have declared the input and output file name strings and file streams thus
ifstream fpInputFile, fpOutputFile;
string inputFileName="", outputFileName="";
The input file name is assigned the name of an existing file as an input argument to the application. The output file name is given the same as the input name except that "_output" is inserted before the final period. So the output is written to the same directory as the input is located. Also I start netbeans with
su netbeans
so the IDE has root privileges to the directory. I try to open the files, and check whether they are opened thus.
fpInputFile.open(inputFileName.c_str(), ifstream::in);
fpOutputFile.open(outputFileName.c_str(), ifstream::out);
if (!(fpInputFile.is_open())) throw ERROR_OPENING_FILE;
if (!(fpOutputFile.is_open())) throw ERROR_OPENING_FILE;
The input file opens successfully but the output file does not.
Any help in determining why the output file is not opening for writing would be most appreciated.
Declare the output file as an ofstream rather than a ifstream.
You could also use a fstream for both input and output files.
The obvious problem is that you probably meant to open the file using a std::ofstream rather than an std::ifstream. This helps with actually writing to the stream although there are ways to write to an std::ifstream as long as it is opened for reading. For example, you could use the std::streambuf interface directly or use the std::streambuf to construct and std::ostream.
The more interesting question is: why isn't the file opened for writing when std::ios_base::in | std::ios_base::out is used for the open mode? std::ifstream automatically adds std::ios_base::in. It turns out, that the mode std::ios_base::in | std::ios_base::out doesn't create a file but it would successfully open an existing file. If you really want use an std::ifstream to open a file for output which potentially doesn't exist you would need to use either std::ios_base::out | std::ios_base::trunc or std::ios_base::out | std::ios_base::app:
the former would force the file to be created or truncated if it exists
the latter would force writes to append to the file in all cases
My personal guess is, however, that you are best off just using std::ofstream or, if you want to open the file for both reading and writing std::fstream (which, however, would also need to have std::ios_base::trunc or std::ios_base::app added to create a file if none exists).
I am opening a file with ifstream to check if it exists. Then I close it and open it with ofstream to write to it, and I think setting ios::trunc flag allows me to overwrite it.
However I'd like the ability to keep the file open if it exists, but I used an ifstream to open it so does that mean I can't write to the file till I close and re-open using fstream or ofstream? I didn't use fstream to begin with because that wouldn't tell me if the file was already there or not.
Just open a read-write fstream on the file. You can test if the file previously existed (and was non-empty) by seeking to the end and seeing if you're at a non-zero offset. If so, the file existed, and you can do whatever with it. If not, the file didn't exist or was empty. Assuming you don't need to distinguish between those two cases, you can then proceed as if it did not exist.
For example:
// Error checking omitted for expository purposes
std::fstream f("file.txt", std::ios::in | std::ios::out);
f.seekg(0, std::ios::end)
bool didFileExist = (f.tellg() > 0);
f.seekg(0, std::ios::beg);
// Now use the file in read-write mode. If didFileExist is true, then the
// file previously existed (and has not yet been modified)
The setting ios::trunc erases previous contents of the file.
Try opening the file without this setting; with only the 'write' setting.
this is touching very serios problem - race conditions - what if somebody manages to do something with this file between closing and reopening? unfortunately iostream does not provide any means of resolving that issue - you can use cstdio FILE. If you want to turncate file if exists or create new one if not use fopen(name, "w"). If you want to turncate file if it exists or fail otherwise, then it seems standard library has nothing to offer, and you should go to other libraries or platform specific functions like OpenFile in windows.h