Когда `ifstream :: readsome` устанавливает` eofbit`?

Этот код повторяется вечно:

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    std::ifstream f(argv[1]);
    std::ostringstream ostr;

    while(f && !f.eof())
    {
        char b[5000];
        std::size_t read = f.readsome(b, sizeof b);
        std::cerr << "Read: " << read << " bytes" << std::endl;
        ostr.write(b, read);
    }
}

Это потому, что readsome никогда не устанавливает eofbit .

cplusplus.com говорит:

Об ошибках сообщается путем изменения флагов внутреннего состояния:

eofbit Указатель получения находится в конце внутреннего ввода буфера потока. массив при вызове функции, что означает отсутствие позиций для читать во внутреннем буфере (который может быть или не быть концом ввода последовательность).Это происходит, когда rdbuf () -> in_avail () вернет -1 перед извлекается первый символ.

failbit Поток находился в конце источника символов перед была вызвана функция.

badbit Произошла иная ошибка, чем указанная выше.

Почти то же самое, стандарт гласит:

[C ++ 11: 27.7.2.3]: размер потока чтения (char_type * s, streamsize n);

32. Эффекты: Ведет себя как неформатированная функция ввода (как описано в 27.7.2.3, п.1). После создания объекта-сторожа if ! Good () вызывает setstate (failbit) , который может вызвать исключение и вернуть. В противном случае экстракты символов и сохраняет их в последовательных местах массива, первый элемент обозначен s . Если rdbuf () -> in_avail () == -1 , вызывает setstate (eofbit) (который может вызвать ios_base :: failure (27.5.5.4)) и извлечь нет символов;

  • Если rdbuf () -> in_avail () == 0 , не извлекает символы
  • Если rdbuf () -> in_avail ()> 0 , извлекает мин (rdbuf () -> in_avail (), n)) .

33. Возвращает: Количество извлеченных символов.

То, что условие in_avail () == 0 не работает, означает, что ifstream :: readsome сам по себе не работает, если буфер потока пуст, но in_avail () == -1 условие означает, что оно установит eofbit , когда какая-то другая операция привела к in_avail ( ) == -1 .

Это кажется несоответствием, даже несмотря на «некоторую» природу readsome .

Так что семантика readsome и eof ? Правильно ли я их истолковал? Являются ли они примером плохого дизайна в библиотеке потоков?


(Украдено из [IMO] недопустимая ошибка libstdc ++ 52169 .)

9
задан Lightness Races with Monica 10 July 2017 в 13:11
поделиться