Does fstream open have trouble with larger files? - c++

I'm trying to open /usr/share/dict/words with the following code:
fstream f;
f.open("/usr/share/dict/words");
// why is this returning false?
bool open = f.is_open();
I'm wondering why f.is_open() is returning false?
More info: when I try a smaller test file containing on the order of 20 lines f.is_open() returns true. Perhaps f.open is trying to load the entire file into memory?

It does not work because you are opening the file for reading and writing. Unless you are running as root, you do not have permissions to write to this file.
If you open it just for reading it will work:
f.open("/usr/share/dict/words", fstream::in);

The fstream.open() function is declared thusly:
void open (const char *filename,
ios_base::openmode mode = ios_base::in | ios_base::out );
i.e. it opens the file for reading and writing. Your process probably does not have permissions to open that file for writing unless you're running as root. Open it for reading only with
f.open("/usr/share/dict/words", ios_base::in);

Related

Default mode of fstream

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.

Trying again and again to open a file while giving wrong path

I've just started working on file using C++ for the first time and I would like to write a correct program which allows me to:
Open the file giving the path;
If it fails to open (showing which error is doesn't matter), ask a new path;
Working on the file;
Close the file;
The only point I can't do is the second one. I've already tryed somethink like:
do{
cout<<"Path: ";cin>>path;
f.open(path, ios::in);
}while(f.fail());
but if I write the path of an inexisting file and then a path of the file I want to open, the program continously ask me a new path and never stops.
P.S. = Will it be different if I want to use that condition to prevent errors while creating a new file using ios::out (for example: a file name/extension which contains illegal characters)?
Clear the flags if its unsuccessful
f.open( path, ios::in ) ;
while( f.fail() )
{
f.clear();
std::cout<<"Incorrect file path, Re-Enter ";
std::cin>>path;
f.open( path, ios::in ) ;
}

Skip EOF while reading a file in C++

Whenever I encounter a substitute character http://en.wikipedia.org/wiki/Substitute_character while reading a file in C++ using getline(), it is interpreted as a EOF so I cannot advance with my reading in order to get the file entire content. So my question is, how can I skip the substitute characters and read the content of the file until the "real" EOF?
Open the file in binary mode instead of text mode. If you're using fopen, make open it in one of the "b" modes, e.g. "rb". If you're using a C++ ifstream object, open it with the ios::binary flag.
For example:
// C method
FILE *f = fopen("filename", "rb");
// C++ method
std::ifstream f("filename", std::ios::in | std::ios::binary);

ifstream not creating and opening a file for output

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).

How to edit (read and then write) a file with c++ filestreaming?

For example, if I need to add a sentence to the end of a file. I have to first open the file (e.g. "a.txt"), by
ofstream outfile.open("a.txt");
But whenever I do this, I will overwrite the existing "a.txt" in the same directory. Is it possible to edit the file like first read and then write?
Thank you very much.
You want to open the file in 'append' mode. Passing ios::app to the open method causes the file to be opened in append mode.
f.open("file.txt", ios::app);
See http://www.cplusplus.com/reference/iostream/ios_base/openmode/ for other flags
Try this:
std::ofstream outfile( "a.txt", std::ios_base::app | std::ios_base::ate );
Various references:
http://www.cplusplus.com/reference/iostream/ofstream/ofstream/
http://www.cplusplus.com/reference/iostream/ofstream/open/
http://msdn.microsoft.com/en-us/library/aa277521(v=vs.60).aspx
http://msdn.microsoft.com/en-us/library/aa266859(v=vs.60).aspx