John Allison
John Allison

Reputation: 996

while (cin >> *pchar) awaits further input after Ctrl-Z

In my Introduction to C++ classes, we were asked to write a function that returns the length of a string using pointers. The code that I wrote (see full code below) seems to work just fine, but here's the thing I don't understand.

I would think typing 'Yes' followed by Ctrl-Z ( I'm using Windows 10) in the console would stop the input. However, after pressing Ctrl-Z -> Enter the console still waits for further input. I have to start a new line after 'Yes', press Ctrl-Z and then hit Enter again to stop the input.

Why is this the case? Is there a way to stop the input after pressing just Ctrl-Z without any of the two new lines?

I read several posts on cin here, including this, this, and this, but they don't seem to answer my question.

#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;
}

Upvotes: 0

Views: 433

Answers (2)

Kagiso Marvin Molekwa
Kagiso Marvin Molekwa

Reputation: 979

Firstly we have to understand what you while loop actually does.

while (cin >> *pchar) pchar++; says that continue getting input from the stdin whilst cin has not encountered an error (or to be specific whilst !cin.fail() == true).

Note that cin is basically an object of std::istream.

Then secondly we have to understand what causes std::istream::fail to return true. Here they are saying that std::istream::fail returns true if the badbit or failbit flags are set (and/or also if any non EOF error occurs).

Having said that, Ctrl-Z is actually EOF (end of file). And based on what I have said above, std::istream::fail will return true if any none EOF error occurs, and of course return false if an EOF occurs.

So in short, EOF/Ctrl-Z does not cause std::istream::fail to return true hence the loop will continue running.

If you really want to have your program cease executing when EOF/Ctrl-Z gets hit, then adjust your loop to something like this...

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

Now the loop above reads, whilst std::istream::fail() == false and no EOF/Ctrl-Z character has been entered, continue looping. Else cease the loop.

I hope that fully answers you.

Upvotes: 1

M.M
M.M

Reputation: 141618

If you press Ctrl-Z after typing some other text, it flushes the line buffer (it does not set end-of-file condition).

You have to press it twice in a row; or press it after a newline; to cause the end-of-file condition to occur.

Your misunderstanding is to do with the windows console behaviour, not with C++ streams per se.

See also: Why do I require multiple EOF (CTRL+Z) characters?

Upvotes: 2

Related Questions