Когда `ifstream :: readsome` устанавливает` eofbit`?
Этот код зацикливается навсегда:
#include <iostream>
#include <fstream>
#include <sstream>
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
При вызове функции указатель get находится в конце внутреннего входного массива буфера потока, что означает отсутствие позиций для чтения во внутреннем буфере (который может быть или не быть концом входной последовательности). Это происходит когдаrdbuf()->in_avail()
вернется-1
до того, как первый символ извлечен.
failbit
Поток находился в конце источника символов до вызова функции.
badbit
Произошла ошибка, отличная от вышеуказанной.
Почти то же самое, стандарт говорит:
[C++11: 27.7.2.3]:
streamsize readsome(char_type* s, streamsize n);
32. Эффекты: Ведет себя как неотформатированная функция ввода (как описано в пункте 27.7.2.3). После постройки сторожевого объекта, если!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
, экстрактыmin(rdbuf()->in_avail(),n))
.33. Возвращает: Количество извлеченных символов.
Чтоin_avail() == 0
условие неоперативное подразумевает, чтоifstream::readsome
сам по себе не работает, если буфер потока пуст, ноin_avail() == -1
условие подразумевает, что онобудем установленeofbit
когдакакая-то другая операция привело кin_avail() == -1
.
Это выглядит как несоответствие, даже несмотря на "некоторую" природуreadsome
.
И чтонаходятся семантикаreadsome
а такжеeof
? Правильно ли я их истолковал? Являются ли они примером плохого дизайна в библиотеке потоков?
(Украдено из [IMO] недействительноlibstdc ++ ошибка 52169.)