rubenvb
rubenvb

Reputation: 76519

Contents of the string after failed extraction from istream

If I do this:

ifstream stream("somefilewhichopenssuccesfully.txt");
string token;
if( stream >> token )
    cout << token;
else
    cout << token;

Is the output in the second case guaranteed to be an empty string? I can't seem to find the answer to this on cplusplus.com.

Thanks!

Upvotes: 3

Views: 245

Answers (3)

Bo Persson
Bo Persson

Reputation: 92261

No, even if the operation fails, the string will contain the characters extracted so far.

The standard says (§21.4.8.9):

Effects: Behaves as a formatted input function (27.7.2.2.1). After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1,c). If is.width() is greater than zero, the maximum number n of characters appended is is.width(); otherwise n is str.max_size(). Characters are extracted and appended until any of the following occurs:
— n characters are stored;
— end-of-file occurs on the input sequence;
isspace(c,is.getloc()) is true for the next available input character c.

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361402

Is the output in the second case guaranteed to be an empty string?

The answer is : no, because it depends, as described below.

Since else block will be executed only if an attempt to read from the stream fails, and that can occur anytime in the course of reading.

  • If it fails at the very first attempt, then there is no character extraction from the stream, and hence token will be empty (as it was).

  • If it fails after few reads, then token will not be empty. It will contain the characters successfully read so far from the stream.

The section §21.3.7.9 from the Standard says,

Begins by constructing a sentry object k as if k were constructed by typename basic_istream::sentry k(is). If bool(k) is true, it calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1,c). If is.width() is greater than zero, the maximum number n of characters appended is is.width(); otherwise n is str.max_size(). Characters are extracted and appended until any of the following occurs:

— n characters are stored;

— end-of-file occurs on the input sequence;

— isspace(c,is.getloc()) is true for the next available input character c.

After the last character (if any) is extracted, is.width(0) is called and the sentry object k is destroyed.

If the function extracts no characters, it calls is.setstate(ios::failbit), which may throw ios_base::failure (27.4.4.3).


Also note that the section §21.3.1/2 from the Standard guarantees that the default constructed string will be empty. The Standard says its size will be zero, that means, empty.

Upvotes: 2

Nim
Nim

Reputation: 33655

I deleted my original answer because I wanted to test this. This is what I see, if there is an error whilst reading (EOF is not counted in this context), the original string is modified and the branch sees the modified version. To test I did the following, created a 2Gb file (touch then truncate), the above code to read. Whilst the code was running, removed the file (this should set the failbit - I think). Immediately stops reading, but the string is modified - it has a larger size.

To me this indicates that the string is modified even if the stream operation fails.

Upvotes: 1

Related Questions