while (cin >> * pchar) ожидает дальнейшего ввода после нажатия Ctrl-Z - PullRequest
0 голосов
/ 19 ноября 2018

В моем введении в классы C ++ нас попросили написать функцию, которая возвращает длину строки с использованием указателей. Код, который я написал (см. Полный код ниже), кажется, работает просто отлично, но вот что я не понимаю.

Я бы подумал, что ввод «Да», а затем Ctrl-Z (я использую Windows 10) в консоли остановит ввод. Однако после нажатия Ctrl-Z -> Enter консоль все еще ждет дальнейшего ввода. Я должен начать новую строку после «Да», нажмите Ctrl-Z, а затем снова нажмите Enter, чтобы остановить ввод.

Почему это так? Есть ли способ остановить ввод после нажатия только Ctrl-Z без любой из двух новых строк?

Я прочитал несколько постов на cin здесь, включая это , это и это , но они, похоже, не отвечают на мой вопрос.

#include "pch.h"
#include <iostream>
using namespace std;

unsigned strlen(const char *str)
{
    int count = 0;
    while (*str != '\0') { str++; count++; }
    return count;
}

int main()
{
    char str[100] = {};
    char *pchar;
    pchar = str;
    while (cin >> *pchar) pchar++;
    pchar = str;
    cout << '\n' << strlen(pchar);
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Если вы нажмете Ctrl-Z после ввода какого-либо другого текста, он очищает буфер строки (он не устанавливает условие конца файла).

Вы должны нажать на нее дважды подряд; или нажмите его после новой строки; вызывать условие конца файла.

Ваше недоразумение связано с поведением консоли Windows, а не с потоками C ++ как таковыми.

См. Также: Почему мне требуется несколько символов EOF (CTRL + Z)?

0 голосов
/ 19 ноября 2018

Во-первых, мы должны понять, что в действительности делает цикл while.

while (cin >> *pchar) pchar++; говорит, что продолжает получать данные от stdin, пока cin не обнаружил ошибку (или, если быть точным, пока !cin.fail() == true).

Обратите внимание, что cin в основном является объектом std::istream.

Затем, во-вторых, мы должны понять, что заставляет std::istream::fail возвращать true. Здесь они говорят, что std::istream::fail возвращает true, если установлены флаги badbit или failbit (и / или также, если возникает какая-либо не ошибка EOF).

Сказав это, Ctrl-Z на самом деле EOF (конец файла). И исходя из того, что я сказал выше, std::istream::fail вернет true, если возникнет ошибка none EOF, и, конечно, вернет false, если EOF произойдет.

Короче говоря, EOF / Ctrl-Z не заставляет std::istream::fail вернуть true, следовательно, цикл продолжит работать.

Если вы действительно хотите, чтобы ваша программа перестала выполняться при нажатии EOF / Ctrl-Z, настройте ваш цикл на что-то вроде этого ...

 while ((cin >> *pchar) && !cin.eof()) pchar++;

Теперь цикл выше читает, пока std::istream::fail() == false и no EOF / Ctrl-Z введен символ, продолжайте цикл. Остальное прекратить петлю.

Надеюсь, это полностью ответит вам.

...