stringstream.rdbuf causing cout to fail - c++

I was surprised to see my program suddenly go quiet when I added a cout at some point, so I isolated the responsible code:
std::stringstream data;
data<<"Hello World\n";
std:std::fstream file{"hello.txt", std::fstream::out};
file<<data.rdbuf();
std::cout<<"now rdbuf..."<<std::endl;
std::cout<<data.rdbuf()<<std::endl;
std::cout<<"rdbuf done."<< std::endl;
The program quietly exits without the final cout. What is going on? If I change the last .rdbuf() to .str() instead then it completes.

During the call to std::cout<<data.rdbuf(), std::cout is unable to read any characters from data's filebuf because the read position is already at the end of the file after the previous output; accordingly, this sets failbit on std::cout, and until this state is cleared any further output will fail too (i.e. your final line is essentially ignored).
std::cout<<data.str()<<std::endl; will not cause cout to enter a failed state because data.str() returns a copy of the underlying string regardless of where the read position is (for mixed-mode stringstreams anyway).

Related

Does ostringstream object need to be cleared?

I am using an ostringstream object in an application that runs for a long time to print debug information to standard out. I toggle whether the application actually prints and clears the ostringstream object based on a command line arg (e.g., verbose flag). When the verbose switch is not asserted I still write to the ostringstream object but I never clear it.
I am trying to figure out how bad this is and whether I should take more care on clearing the object? Are there any negative repercussions such as using too much memory?
// example code
ostringstream oss;
while (1){
oss << " still alive " << endl;
if (verbose) { cout << oss.str(); oss.str("") }
}
Obviously when you keep inserting data in the stream it'll consume more memory, which at some point can be a lot.
Clearing it will prevent that.

Example of Why stream::good is Wrong?

I gave an answer which I wanted to check the validity of stream each time through a loop here.
My original code used good and looked similar to this:
ifstream foo("foo.txt");
while (foo.good()){
string bar;
getline(foo, bar);
cout << bar << endl;
}
I was immediately pointed here and told to never test good. Clearly this is something I haven't understood but I want to be doing my file I/O correctly.
I tested my code out with several examples and couldn't make the good-testing code fail.
First (this printed correctly, ending with a new line):
bleck 1
blee 1 2
blah
ends in new line
Second (this printed correctly, ending in with the last line):
bleck 1
blee 1 2
blah
this doesn't end in a new line
Third was an empty file (this printed correctly, a single newline.)
Fourth was a missing file (this correctly printed nothing.)
Can someone help me with an example that demonstrates why good-testing shouldn't be done?
They were wrong. The mantra is 'never test .eof()'.
Why is iostream::eof inside a loop condition considered wrong?
Even that mantra is overboard, because both are useful to diagnose the state of the stream after an extraction failed.
So the mantra should be more like
Don't use good() or eof() to detect eof before you try to read any further
Same for fail(), and bad()
Of course stream.good can be usefully employed before using a stream (e.g. in case the stream is a filestream which has not been successfully opened)
However, both are very very very often abused to detect the end of input, and that's not how it works.
A canonical example of why you shouldn't use this method:
std::istringstream stream("a");
char ch;
if (stream >> ch) {
std::cout << "At eof? " << std::boolalpha << stream.eof() << "\n";
std::cout << "good? " << std::boolalpha << stream.good() << "\n";
}
Prints
false
true
See it Live On Coliru
This is already covered in other answers, but I'll go over it briefly for completeness. The only functional difference with
while(foo.good()) { // effectively same as while(foo) {
getline(foo, bar);
consume(bar); // consume() represents any operation that uses bar
}
And
while(getline(foo, bar)){
consume(bar);
}
Is that the former will do an extra loop when there are no lines in the file, making that case indistinguishable from the case of one empty line. I would argue that this is not typically desired behaviour. But I suppose that's matter of opinion.
As sehe says, the mantra is overboard. It's a simplification. What really is the point is that you must not consume() the result of reading the stream before you test for failure or at least EOF (and any test before the read is irrelevant). Which is what people easily do when they test good() in the loop condition.
However, the thing about getline(), is that it tests EOF internally, for you and returns an empty string even if only EOF is read. Therefore, the former version could maybe be roughly the similar to following pseudo c++:
while(foo.good()) {
// inside getline
bar = ""; // Reset bar to empty
string sentry;
if(read_until_newline(foo, sentry)) {
// The streams state is tested implicitly inside getline
// after the value is read. Good
bar = sentry // The read value is used only if it's valid.
// ... // Otherwise, bar is empty.
consume(bar);
}
I hope that illustrates what I'm trying to say. One could say that there is a "correct" version of the read loop inside getline(). This is why the rule is at least partially satisfied by the use of readline even if the outer loop doesn't conform.
But, for other methods of reading, breaking the rule hurts more. Consider:
while(foo.good()) {
int bar;
foo >> bar;
consume(bar);
}
Not only do you always get the extra iteration, the bar in that iteration is uninitialized!
So, in short, while(foo.good()) is OK in your case, because getline() unlike certain other reading functions, leaves the output in a valid state after reading EOF bit. and because you don't care or even do expect the extra iteration when the file is empty.
both good() and eof() will both give you an extra line in your code. If you have a blank file and run this:
std::ifstream foo1("foo1.txt");
std::string line;
int lineNum = 1;
std::cout << "foo1.txt Controlled With good():\n";
while (foo1.good())
{
std::getline(foo1, line);
std::cout << lineNum++ << line << std::endl;
}
foo1.close();
foo1.open("foo1.txt");
lineNum = 1;
std::cout << "\n\nfoo1.txt Controlled With getline():\n";
while (std::getline(foo1, line))
{
std::cout << line << std::endl;
}
The output you will get is
foo1.txt Controlled With good():
1
foo1.txt Controlled With getline():
This proves that it isn't working correctly since a blank file should never be read. The only way to know that is to use a read condition since the stream will always be good the first time it reads.
Using foo.good() just tells you that the previous read operation worked just fine and that the next one might as well work. .good() checks the state of the stream at a given point. It does not check if the end of the file is reached. Lets say something happened while the file was being read (network error, os error, ...) good will fail. That does not mean the end of the file was reached. Nevertheless .good() fails when end of file is reached because the stream is not able to read anymore.
On the other hand, .eof() checks if the end of file was truly reached.
So, .good() might fail while the end of file was not reached.
Hope this helps you understand why using .good() to check end of file is a bad habit.
Let me clearly say that sehe's answer is the correct one.
But the option proposed by, Nathan Oliver, Neil Kirk, and user2079303 is to use readline as the loop condition rather than good. Needs to be addressed for the sake of posterity.
We will compare the loop in the question to the following loop:
string bar;
while (getline(foo, bar)){
cout << bar << endl;
}
Because getline returns the istream passed as the first argument, and because when an istream is cast to bool it returns !(fail() || bad()), and since reading the EOF character will set both the failbit and the eofbit this makes getline a valid loop condition.
The behavior does change however when using getline as a condition because if a line containing only an EOF character is read the loop will exit preventing that line from being outputted. This doesn't occur in Examples 2 and 4. But Example 1:
bleck 1
blee 1 2
blah
ends in new line
Prints this with the good loop condition:
bleck 1
blee 1 2
blah
ends in new line
But chops the last line with the getline loop condition:
bleck 1
blee 1 2
blah
ends in new line
Example 3 is an empty file:
Prints this with the good condition:
Prints nothing with the getline condition.
Neither of these behaviors are wrong. But that last line can make a difference in code. Hopefully this answer will be helpful to you when deciding between the two for coding purposes.

Infinite Loop due to cout<<cin.rdbuf(), why?

i write a program for read input from console and write agian on console. So i used following code.
#include<iostream>
int main()
{
using namespace std;
cout<<cin.rdbuf();
cin.get();
return 0;
}
but it goes in infinite loop. always getting input and printing it back. can anyone explain , what is happening here ?
it generate following output:
(wait for input : enter g)
g
g
(again wait for input : enter h (any char))
h
h
(still wait for input : enter h (any char))
h
h
so on, program always wait for input when i enter any charecter it just print it. again wait for input. it do not terminate
Interesting behaviour.
With your line cout<<cin.rdbuf(); you are calling: ostream& operator<< (streambuf* sb );
From http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/:
(2) stream buffers
Retrieves as many characters as possible from the input sequence controlled by the stream buffer object pointed by sb (if any) and inserts them into the stream, until either the input sequence is exhausted or the function fails to insert into the stream.
Internally, the function accesses the output sequence by first constructing a sentry object. Then (if good), it inserts characters into its associated stream buffer object as if calling its member function sputc, and finally destroys the sentry object before returning.
I assume internally this function calls some kind of getString on the streambuffer in a loop. This one will probably wait for key inputs and forward them to the ostream. The streambuffer is never empty but waits for some user input.
For an exact answer, the implementaiton of the << operator should be read.
Are you sure that you're generating an end of file on standard
in? The definition of << on an std::streambuf* is to read
until end of file on the streambuf. Basically, it is something
along the lines of:
while ( sb->sgetc() != EOF ) {
this->rdbuf()->sputc( sb->sbumpc() );
}
This is simplified; an actual implementation will have to do
error checking on the sputc, and set iostate bits in the
destination as well, according to what has actually happened.
But this is a basic abstraction. And for optimization reasons,
a real implementation will probably use sgetn instead of sgetc/sbumpc.

What happened to << when using ofstream without any filename pointed?

(1) default constructor
Constructs an ofstream object that is not associated with any file.
Internally, its ostream base constructor is passed a pointer to a newly constructed filebuf object (the internal file stream buffer).
what happened to << when using ofstream without any filename pointed?
ofstream ofstream;
ofstream<<1<<endl;
where is the "1" go? is there any problems? I tried it, no issues. but I can't found any code clue for this, can anybody show the internal code explain for it?
Nothing happens.
[C++11: 27.9.1.1/3]: In particular:
If the file is not open for reading the input sequence cannot be read.
If the file is not open for writing the output sequence cannot be written.
A joint file position is maintained for both the input sequence and the output sequence
The stream is closed, an error flag is set and the data is ignored.
Example:
#include <iostream>
#include <fstream>
int main()
{
std::ofstream ofs;
ofs << 1 << std::endl;
std::cout << ofs.good() << std::endl;
}
// Output: 0
Live demo
The short version: the operations on the ofstream all fail, causing nothing to happen. The data that you write is lost and not stored anywhere, and the failbit will be set, causing the stream's fail() member function to return true.
The long version: when an ofstream is constructed without specifying a file, it default-constructs a filebuf. This creates a filebuf where is_open evaluates to false. As part of the stream insertion operation, the data to be written will need to be sent to the disk by calling filebuf::overflow, which, since is_open is false, will return EOF, causing the operation to fail.
Hope this helps!

Different EOF behavior with read versus ignore

I was recently just tripped up by a subtle distinction between the behavior of std::istream::read versus std::istream::ignore. Basically, read extracts N bytes from the input stream, and stores them in a buffer. The ignore function extracts N bytes from the input stream, but simply discards them rather than storing them in a buffer. So, my understanding was that read and ignore are basically the same in every way, except for the fact that read saves the extracted bytes whereas ignore just discards them.
But there is another subtle difference between read and ignore which managed to trip me up. If you read to the end of a stream, the EOF condition is not triggered. You have to read past the end of a stream in order for the EOF condition to be triggered. But with ignore it is different: you only need to read to the end of a stream.
Consider:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
{
std::stringstream ss;
ss << "abcd";
char buf[1024];
ss.read(buf, 4);
std::cout << "EOF: " << std::boolalpha << ss.eof() << std::endl;
}
{
std::stringstream ss;
ss << "abcd";
ss.ignore(4);
std::cout << "EOF: " << std::boolalpha << ss.eof() << std::endl;
}
}
On GCC 4.4.5, this prints out:
EOF: false
EOF: true
So, why is the behavior different here? This subtle difference managed to confuse me enough to wonder why there is a difference. Is there some compelling reason that EOF is triggered "early" with a call to ignore?
eof() should only return true if you have already attempted to read past the end. In neither case should it be true. This may be a bug in your implementation.
I'm going to go out on a limb here and answer my own question: it really looks like this is a bug in GCC.
The standard reads in 27.6.1.3 paragraph 23:
[istream::ignore] behaves as an
unformatted input function (as
described in 27.6.1.3, paragraph 1).
After constructing a sentry object,
extracts characters and discards them.
Characters are extracted until any of
the following occurs:
if n != numeric_limits::max()
(18.2.1), n characters are extracted
end-of-file occurs on the input sequence (in which case the function
calls setstate(eofbit), which may
throw ios_base::failure(27.4.4.3));
c == delim for the next available input character c (in which case c is
extracted). Note: The last condition
will never occur if delim ==
traits::eof()
My (somewhat tentative) interpretation is that GCC is wrong here, because of the bold parts above. Ignore should behave as an unformatted input function, (like read()), which means that end-of-file should only occur on the input sequence if there is an attempt to extract additional bytes after the last byte in the stream has been extracted.
I'll submit a bug report if I find that enough people agree with this answer.
The consensus seemed to be that this was a legitimate bug in gcc. Since I saw no indication a bug report had been filed, I'm doing so now. The report can be viewed at:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51651