istream::getline возвращаемый тип

Что возвращает метод istream::getline?

Я спрашиваю, потому что я видел, что для циклического просмотра файла это нужно делать так:

while ( file.getline( char*, int ) )
{
    // handle input
}

Что возвращается?


person Community    schedule 16.01.2011    source источник
comment
да, я должен был сказать, что я уже знаю это. но очевидно, что в этом есть что-то странное, потому что от него происходит какая-то форма истинного или ложного.   -  person    schedule 17.01.2011
comment
Он перегружает операторы bool или void*, поэтому, когда он неявно приводится в условии if(), он может возвращать независимо от того, был ли достигнут EOF или нет.   -  person Cameron    schedule 17.01.2011


Ответы (5)


Он возвращает поток, чтобы мы могли связать операцию.

Но когда вы используете объект в логическом контексте, компилятор ищет оператор преобразования, который может преобразовать его в тип, который можно использовать в логическом контексте.

C++11

В этом случае поток имеет explicit operator bool() const. При вызове проверяет флаги ошибок. Если установлены failbit или badbit, то возвращается false, в противном случае возвращается true.

C++03

В этом случае поток имеет operator void*() const. Поскольку это приводит к указателю, его можно использовать в логическом контексте. При вызове проверяет флаги ошибок. Если установлены либо failbit, либо badbit, то он возвращает NULL, что эквивалентно FALSE, в противном случае он возвращает указатель на себя (или что-то еще действительное, хотя вы не должны использовать этот факт)).

использование

Таким образом, вы можете использовать поток в любом контексте, который требует логического теста:

if (stream >> x)
{    
}

while(stream)
{
    /* do Stuff */
}

Примечание. Не рекомендуется тестировать поток снаружи, а затем читать/записывать его внутри тела условного оператора/оператора цикла. Это потому, что акт чтения может сделать поток плохим. Обычно лучше делать чтение как часть теста.

while(std::getline(steam, line))
{
    // The read worked and line is valid.
}
person Martin York    schedule 16.01.2011

Взгляните на справку. istream, возвращенный из getline, преобразуется в bool с помощью неявного преобразования для проверки успеха операция. Это преобразование превращает использование if(mystream.getline(a,b)) в сокращение для if(!mystream.getline(a,b).fail()).

person Öö Tiib    schedule 16.01.2011
comment
Ваша ссылка не содержит ничего согласующегося с вашим утверждением. - person iheanyi; 09.05.2014
comment
@iheanyi Добавлено уточнение, возможно, страницы со временем изменились. - person Öö Tiib; 09.05.2014

Он возвращает сам поток. Поток может преобразовываться (через void*) в bool, указывающий его состояние. В этом примере ваш цикл while завершится, когда преобразование потока в bool станет "ложным", что происходит, когда ваш поток входит в состояние ошибки. В вашем коде это, скорее всего, произойдет, когда была попытка прочитать за конец файла. Короче говоря, он будет читать столько, сколько есть, а затем остановится.

person Lightness Races in Orbit    schedule 16.01.2011
comment
+1. Он может конвертироваться в bool, потому что перегружает operator bool() (или operator void*(), не знаю какой) - person Cameron; 17.01.2011
comment
@Cameron: Это operator void*(). - person Lightness Races in Orbit; 17.01.2011

Функция возвращает ссылку на сам объект потока, который можно использовать либо для цепочки дальнейших операций чтения:

myStream.getline(...).getline(...);

или, поскольку потоки неявно преобразуются в void *s, в цикле или условии:

while (myStream.getline(...)) {
    ...
}

Подробнее об этом можно прочитать на сайте cplusplus.com:

http://cplusplus.com/reference/iostream/istream/getline/

person templatetypedef    schedule 16.01.2011

Все говорили вам, что это такое, теперь позвольте мне рассказать вам, используйте бесплатную форму версия

std::string line; 
while(getline(file, line)) // assuming file is an instance of istream
{
//
}

Почему эта версия? Это должно сразу стать очевидным - вы передаете std::string, а не какой-то символьный буфер фиксированного размера!

person Nim    schedule 16.01.2011
comment
но что, если вы хотите char* вместо std::string? это ситуация, в которой я нахожусь. - person ; 17.01.2011
comment
std::string имеет метод c_str(), который вернет вам то, что вам нужно, если вам нужно изменить строку, то есть методы std::string, которые вы можете использовать для ее изменения. - person Nim; 17.01.2011