С++ istream: всегда ли gcount() устанавливается после read(), даже если он терпит неудачу?

Я читаю некоторые данные, используя istream и read(). Я хотел бы знать, могу ли я просто проверить gcount() для байтов или мне нужно проверить некоторую комбинацию good(), eof() и т. д. перед вызовом gcount(). Другими словами, всегда ли gcount() устанавливается после read(), даже если это чтение не удалось из-за EOF или какой-либо другой внутренней проблемы?

Также, если это описано в стандарте или где-то, что вы можете процитировать. Я использую cplusplus.com в качестве ссылки, и в нем говорится, что gcount «возвращает количество символов, извлеченных последней операцией неформатированного ввода, выполненной с объектом». Могу ли я интерпретировать такие утверждения, как «последняя операция», как означающую последнюю операцию, независимо от результата?


person loop    schedule 27.02.2014    source источник
comment
Я ожидаю, что вы можете вызывать gcout() в любом состоянии, пока поток создан. Чего вы ДЕЙСТВИТЕЛЬНО пытаетесь достичь? Если вы вызываете read и следующее, что происходит, это то, что файл достигает EOF, приемлемо ли, что gcount() возвращает 0?   -  person Mats Petersson    schedule 28.02.2014
comment
gcount() подсчитывает все извлеченные символы. И поток может извлекать символы, а затем завершаться ошибкой во время той же операции ввода-вывода. Он не сбрасывается на 0 в случае сбоя извлечения.   -  person 0x499602D2    schedule 28.02.2014


Ответы (1)


Всегда ли gcount() устанавливается после read(), даже если это чтение не удалось из-за EOF или какой-либо другой внутренней проблемы?

Да

Работа gcount() заключается исключительно в том, чтобы вернуть количество символов, извлеченных из последней операции неформатированного ввода. Стандарт не делает различий между значением gcount() при успешном извлечении и при неудаче. И очевидно, что если операция ввода не может извлечь символы, то значение будет 0.

Таким образом, все, что вам нужно проверить, удалось ли извлечение, — это использовать его в качестве условия. Используйте только gcount() в условии, только если вы хотите определить, было ли извлечено определенное количество символов.

person 0x499602D2    schedule 28.02.2014
comment
В вашем примере не будет ли оператор if оцениваться как ложный, если попытка чтения 5 байтов вернет меньшее n, например 4? Прямо сейчас у меня есть код, который зацикливается на чтении потока вроде is.read(data,sizeof data); if(is.gcount()) {//process bytes read} else {//out of bytes to read} - person loop; 28.02.2014
comment
Нет, если is.gcount() не равно нулю, то оно оценивается как true. - person 0x499602D2; 01.03.2014
comment
Извините, если это беспокоит, я просто пытаюсь обдумать ваш пример, поэтому я еще не принял ответ. is.read() возвращает значение is, которое после чтения большего количества байтов, чем доступно, становится ложным. Например, это возвращает false, если one.txt имеет размер ‹1024: ifstream file("one.txt"); istream &is = file; char data[1024]; if (is.read(data, sizeof data) && is.gcount()) { cout << "true" << endl; } else { cout << "false" << endl; } - person loop; 01.03.2014
comment
@test Да, но это не имеет ничего общего с gcount(). Это связано с тем, что поток попал в EOF при извлечении. Таким образом, он устанавливает failbit в потоке, что является причиной того, что первое условие возвращает false. - person 0x499602D2; 01.03.2014
comment
@test Я действительно думаю, что допустил ошибку, отвечая на свой пост. Вы не должны использовать && is.gcount() в качестве второго условия. Просто используйте его, чтобы узнать, сколько символов было извлечено, вот и все. - person 0x499602D2; 01.03.2014
comment
Хорошо, спасибо. Не могли бы вы отредактировать свой ответ, чтобы уточнить или удалить пример, тогда я приму ответ. - person loop; 01.03.2014