Jake
Jake

Reputation: 938

getline(cin, string) not working EVEN WITH cin.ignore()

There are several questions on this site referring to getline not working, the apparent solution is that there are remaining newline characters in the buffer that need to be cleared, supposedly with cin.ignore(). I've tried so many variations of this and nothing seems to work, all I'm trying to do is simple console input and cin >> string isn't an option because the string might have spaces.

Here is my code.

void prompt(std::string * str)
{
    cout << "> ";

    cin.sync();
    cin.get();
    cin.ignore(256, '\r');
    cin.ignore(256, '\n');
    cin.ignore();
    cin.ignore();

    std::string tmp;
    getline(cin, tmp);

    cin.sync();
    cin.get();
    cin.ignore(256, '\r');
    cin.ignore(256, '\n');

    *str = tmp;
}

As you can see I've tried all sorts of things. It still skips right over getline(cin,tmp) and appears to set str to an empty string. Please help. Thank you for your time.

Upvotes: 0

Views: 2625

Answers (2)

Ben Voigt
Ben Voigt

Reputation: 283981

Once any formatted extraction has failed, the failbit will be set on your stream, and future operations will do nothing at all. This is somewhat convenient because you can handle errors in groups, instead of checking after every single operation. But once you detect an error, you need to reset the failbit in order to try something different. The command to do that is pretty simple:

cin.reset();

Upvotes: 2

Galik
Galik

Reputation: 48675

Passing variables using pointers is discouraged. If you want to get the value back from the function references & are recomended.

I don't know the context you are calling prompt() in but here is a suggestion for implementing prompt() that may work better for you.

#include <algorithm>
#include <iostream>
#include <string>

// return bool so you know if it failed or not
bool prompt(std::string& s) // use reference
{
    std::cout << "> ";
    return std::getline(std::cin >> std::ws, s);
 }

int main()
{
    char c;
    std::string s;

    do
    {
        if(!prompt(s)) // always check the imput
            break;

        // process the string (reverse it for example...)
        std::reverse(s.begin(), s.end());
        std::cout << "reversed: " << s << '\n';

        std::cout << "Another go? [y/n]: ";
    }
    while(std::cin.get(c) && std::tolower(c) == 'y');
}

Upvotes: 0

Related Questions