Value stored when istream read fails

后端 未结 2 1383
抹茶落季
抹茶落季 2021-01-22 20:23

Sample code:

#include 

int main()
{
    int x = 5;
    std::cin >> x;
    std::cout << x << \'\\n\';
}

On on

相关标签:
2条回答
  • 2021-01-22 21:18

    According to 27.7.2.2.1 [istream.formatted.reqmts] paragraph 1 the first things for the formatted input function is to construct an std::istream::senty object. Further processing depends on whether this object converts to true or false: nothing happens to the value if the sentry converts to false.

    According to 27.7.2.1.3 [istream::sentry] paragraphs 5 and 7 the sentry will convert to false if the stream's flags are not std::ios_base::goodbit. That is, if either a failure happend or EOF is reached the sentry will convert to false. As a result, the value stays at 5 when EOF is reached after skipping whitespace, assuming std::ios_base::skipws is set. Unsetting std::ios_base::skipws should result in the value becoming 0 if there is, at least, one space.

    Once parsing is actually done, the applies logic is defined in 22.4.2.1.2 [facet.num.get.virtuals] paragraph 3, Stage 3. The key section on the affected value is

    ...

    The numeric value to be stored can be one of:

    — zero, if the conversion function fails to convert the entire field. ios_base::failbit is assigned to err.

    — the most positive representable value, if the field represents a value too large positive to be represented in val. ios_base::failbit is assigned to err.

    — the most negative representable value or zero for an unsigned integer type, if the field represents a value too large negative to be represented in val. ios_base::failbit is assigned to err.

    — the converted value, otherwise.

    The resultant numeric value is stored in val.

    So, the observed behavior is correct.

    With pre-C++11 the value was left unchanged in all cases. It was considered desirable to tell errors apart and indicate with the value which value should be represented. The discussions on how to change the behavior went on for a rather long time and were actually quite contentious.

    That the value isn't changed if EOF is reached before attempting a conversion may be considered an error. I don't recall that case to be considered while the change was discussed.

    0 讨论(0)
  • 2021-01-22 21:24

    Yes, this is the correct behaviour since C++11.

    • istream behavior change in C++ upon failure

    The difference in what you're seeing is that a zero is written "when extraction fails", but extraction is not even attempted if EOF is already set on the stream… so nothing happens.

    0 讨论(0)
提交回复
热议问题