2015-03-19 3 views
0

У меня есть этот код:if (! Getline (std :: cin, str1)) break; что это условие проверяет?

while (true){ 
std::string cmdline; 
if (!std::getline(std::cin, cmdline)) break; 

std::istringstream cmdstream(cmdline); 
std::string cmd; 
cmdstream >> cmd; 
...} 

Что означает, если проверка состояния и почему она заканчивается в бесконечном цикле, если я оставлю вне !?

ответ

0

Поскольку в соответствии с: http://www.cplusplus.com/reference/string/string/getline/

Параметр возврата является входной поток, который в данном случае в станд :: CIN, таким образом, если станд :: CIN ввода является пустым, то возврат пуст.

В принципе, пользователь вводил что-нибудь?

3

Так как C++ вставляет неявное сравнение с нуля, эта линия

if (!std::getline(std::cin, cmdline)) break; 

эквивалентно

if (!std::getline(std::cin, cmdline) != 0) break; 

или просто

if (std::getline(std::cin, cmdline) == 0) break; 

std::getline возвращает поток, на котором он называется , Поток преобразуется в bool или в void*, в зависимости от версии библиотеки C++. Преобразованное значение становится равным нулю при достижении конца входа. Вот почему цикл заканчивается, когда нет дополнительного ввода для чтения.

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

std::string cmdline; 
while (std::getline(std::cin, cmdline)) { 
    std::istringstream cmdstream(cmdline); 
    std::string cmd; 
    cmdstream >> cmd; 
    ... 
} 

Это позволяет поместить конечное состояние в заголовке петли, за счет декларирования cmdline вне цикла.

+0

«' std :: getline' возвращает ноль, когда достигнут конец ввода ». Он фактически возвращает сам поток, где он затем преобразуется контекстом в' bool', используя его оператор булевого преобразования. 'std :: getline == 0' - ошибка времени компиляции (в> = C++ 11), в C++ 03 происходит преобразование в' void * ', которое затем сравнивается с константой нулевого указателя' 0' это действительно. – 0x499602D2

+0

@ 0x499602D2 Спасибо за комментарий! Я не хотел вдаваться в мелкие детали здесь, но, я думаю, нет способа избежать этого. – dasblinkenlight

1

std::getline возвращает ссылку на поток, переданный как первый аргумент, который равен std::cin в вашем случае. Это означает, что

if (!std::getline(std::cin, cmdline)) break; 

эквивалентно

std::getline(std::cin, cmdline); 
if (!std::cin) break; 

последняя строка эквивалентна

if (std::cin.fail()) break; 

который будет вырваться из цикла, если getline поднят флаг failbit в потоке. Это происходит, если ошибка ввода-вывода или состояние конца потока предотвратили чтение getline.

Смежные вопросы