Search code examples
c++cingetlineistream

C++ getline is not empty when no input is entered


I am new to c++ and still trying to wrap my head around how input/output streams work.

I am currently trying to write a function to make sure the user enters an int, and tell them if the input is empty or not a valid int.

I am using getline and have tried using cin.clear and cin.ignore but i cannot seem to get this to work and have no idea where i am going wrong.

It works if I input a letter however if i just press enter with nothing input it doesn't say no input detected.

void testStuff()
{
    string number;

    ws(cin);//skips Whitespaces

    if (getline(cin, number) && number.end() !=
        find_if_not(number.begin(), number.end(), &isdigit))
    {
        if (number.empty())
        {
            cout << "No input detected" << endl;
            testStuff();
        }
        cout << "Please input a Valid number" << endl;
        testStuff();
    }
}

Solution

  • Assuming your ws works as specified (skips whitespace in the input), by the time you call getline, something other than whitespace has to have been entered. Thus, when getline gets called, that non-whitespace character has to be waiting in the input buffer, and getline must return a non-empty sequence of characters (i.e., everything from that first non-whitespace character up to the next new-line).

    For example, let's write our own ws that shows what character(s) it's skipping over:

    void ws(std::istream &is) {
        while (std::isspace(is.peek())) {
            char ch;
            is.get(ch);
            std::cout << "Read: " << (int)ch << '\n';
        }
    }
    

    Now, when we call testStuff() and just press enter, we get Read: 10 as our output--i.e., ws has read and skipped the new-line we entered.

    So, to get to the call to getline, the user has to enter something other than whitespace, and a new-line is whitespace. So, but the time getline is called at all, we know there's some non-whitespace character waiting in the input buffer, so when getline is called, it must produce a non-empty result.