How to use different ifstream modes in c++? - c++

According to the reference, if I use ifstream infile ( "test.txt" , ifstream::in ); it will Allow input operations on the stream. But what are some of the examples of the "input operations"?
Is ifstream infile ( "test.txt" , ifstream::in | ifstream::binary ); the right syntax to use multiple flags?
Will it make a difference if I change ifstream:: to iso:: ?
Thank you

According to the reference, if I use ifstream infile ( "test.txt" ,
ifstream::in ); it will Allow input
operations on the stream. But what are
some of the examples of the "input
operations"?
Reading from a file which would mean everything an input stream can support. See istream member functions. Typically, you can do both formatted (using >>) and unformatted reads (using read). Remember that ifstream is a specialization of the basic_ifstream template for char type. Depending on your needs, say to read UTF-16 encoded file, you may have to use a different specialization (wifstream) or even use a special locale (read this to know more about locales).
Is ifstream infile ( "test.txt" , ifstream::in | ifstream::binary );
the right syntax to use multiple
flags?
Yes.
Will it make a difference if I change ifstream:: to iso:: ?
No.

Stream operations are extraction << and insertion >>. When you do the following assuming
file is of fstream type:
file << 5 << 6.5 << "Hello World!"; // insertion of data (output)
file >> x >> y >> str; // exaction of data (input)
You could also, deal with the stream as a binary stream. In that case, it doesn't really look like a "stream" of data but that gives you random access to the data. In some cases you can't use the binary mode, especially if your data is not available like a network stream. Insertion and Extraction, are the two main operations on streams.
ifstream is created as an input stream by default. So, std::ios::in is redundant in this case. You are using the flags correctly.
all streams inherit from ios. So, the flags are available in both places, you can either retrieve them from ios directly or from fstream.

Related

c++ - fstream and ofstream

What is the difference between:
fstream texfile;
textfile.open("Test.txt");
and
ofstream textfile;
textfile.open("Test.txt");
Are their function the same?
ofstream only has methods for outputting, so for instance if you tried textfile >> whatever it would not compile. fstream can be used for input and output, although what will work depends on the flags you pass to the constructor / open.
std::string s;
std::ofstream ostream("file");
std::fstream stream("file", stream.out);
ostream >> s; // compiler error
stream >> s; // no compiler error, but operation will fail.
The comments have some more great points.
Take a look at their pages on cplusplus.com here and here.
ofstream inherits from ostream. 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. In your example, the open mode is ios_base::in | ios_base::out by default. The default open mode of ofstream is ios_base::out. Moreover, ios_base::out is always set for ofstream objects (even if explicitly not set in argument mode).
Use ofstream when textfile is for output only, ifstream for input only, fstream for both input and output. This makes your intention more obvious.

fstream input and output position are the same although inherited from istream and ostream

I want to to delete all data in binary files in the range: 10-19.
fstream myFile(f.bin, ios_base::in | ios_base::out | ios_base::app | ios_base::binary);
myFile.seekg(20);
myFile.seekp(10);
myFile << myFile;
myFile.close();
The problem is that internal position is stored in a single place.
Although here: http://www.cplusplus.com/reference/istream/iostream/
it is stated that it inherited from different base classes, and should been stored twice.
I understand I can use 2 different streams. But I am asking how to achieve this with a single stream?
What about using intermediate stream which is not a file stream- to avoid reopening the file again?

C++ Reading data from a file line by line

I am new to programming and I have this question. I have this file that I am opening
ifstream fin;
FILE * pFile;
pFile = fopen (fname,"r");
The file has 3 data each line. The first is an integer, the second is an alphabet and the third is an address(like computer memory address). How do I extract these line by line into 3 variables that I can process, and then repeat it with next line and so.
You should know that there are preferred C++ methods for manipulation of files over C stdio methods:
Using standard predefined streams: std::ofstream for output and std::ifstream for input.
Formatted/Unformatted I/O such as operator<<(), operator>>(), read() and write().
In-memory I/O for manipulation of extracted data.
What you need for this particular case is input stream functionality along with formatted input. The formatted input will be done through operator>>().
But before you get to that, you have to instantiate a file stream. Since you're using input, std::ifstream will be used:
std::ifstream in("your/path.txt");
The next thing to do is to create the three variables whose values you will extract into the stream. Since you know the types beforehand, the types you will need is an integer, character, and string respectively:
int num;
char letter;
std::string address;
The next thing to do is to use operator>>() to obtain the first valid value from the stream. The way it works is that the function analyses the type of the righthand operand and determines if the characters extracted from the file stream will create a valid value after parsing. When the stream hits whitespace, the new line character or the EOF (end-of-file) character (or a character that doesn't match that of the operand's type), extraction will stop.
What makes IOStreams powerful is that it allows chaining of expressions. So you are able to do this:
in >> num >> letter >> address;
which is equivalent to:
in >> num;
in >> letter;
in >> address;
This is all that is needed for this simple case. In more complex situations, loops and in-memory I/O might be needed for successful extractions.

fstream >> int failing?

Any idea why the following would fail?
std::fstream i(L"C:/testlog.txt", std::ios::binary | std::ios::in);
int test = 0;
i >> test;
fail() is returning true. The file exists and is opened.
I checked
i._Filebuffer._Myfile._ptr
and it is pointer to a buffer of the file so I don't see why it is failing.
You're opening the file in binary mode. The extraction operators were meant to be used with text files. Simply leave out the std::ios::binary flag to open the file in text mode.
If you actually do have a binary file, use the read() function instead.
Edit: I tested it too, and indeed it seems to work. I got this from CPlusPlus.com, where it says:
In binary files, to input and output data with the extraction and insertion operators (<< and >>) and functions like getline is not efficient, since we do not need to format any data, and data may not use the separation codes used by text files to separate elements (like space, newline, etc...).
Together with the description of ios::binary, which simply states "Consider stream as binary rather than text.", I'm utterly confused now. This answer is turning into a question of its own...
The following:
#include <fstream>
#include <iostream>
using namespace std
int main() {
std::fstream i("int.dat" , std::ios::binary | std::ios::in);
int test = 0;
if ( i >> test ) {
cout << "ok" << endl;
}
}
prints "ok" when given a file containing the characters "123". Please post a similar short test that illustrates your code failing.

C++ fstream << and >> operators with binary data

I've always read and been told that when dealing with binary files that one should use read() and write() as opposed to the << and >> operators as they are meant for use with formatted data. I've also read that it is possible to use them, but it is an advanced topic, which I can't find where anyone dives into and discusses.
I recently saw some code which did the following:
std::ifstream file1("x", ios_base::in | ios_base::binary);
std::ofstream file2("y", ios_base::app | ios_base::binary);
file1 << file2.rdbuf();
When I pointed out the use of the << operator with the binary file, I was told that the rdbuf() call returns a streambuf * and that << overloads the streambuf* and does a direct copy with no formatting and is thus safe.
Is this true and also safe? How about efficiency? Any gotchas? Details would be much appreciated.
Thanks!
Yes (see 27.6.2.5.3/6 where the overload of << for streambuf is described).
It's entirely safe and a reasonable way to copy streams.
Note that it also allows stuff like:
std::ifstream file_in1("x1", ios_base::in | ios_base::binary);
std::ifstream file_in2("x2", ios_base::in | ios_base::binary);
std::ofstream file_out("y", ios_base::app | ios_base::binary);
file_out << file_in1.rdbuf() << "\nand\n" << file_in2.rdbuf();
In § 27.7.3.6.3 of the C++ standard, it's mentioned that
basic_ostream<charT,traits>& operator<<
(basic_streambuf<charT,traits>* sb);
Effects: Behaves as an unformatted output function (as described in 27.7.3.7, paragraph 1).
§ 27.7.3.7 describes "unformatted input" which is basically a binary copy. This means that "unformatted" ostream functions are safe for binary data. The other "unformatted" functions mentioned in the standard that I can find are put, write and (officially) flush.