Detect a newline character with getline or istringstream

1.4k views Asked by At

In my program, I'm asking the user for input via getline, and then in a separate class, splitting the string into three different strings which I will then check via a list of pre-determined values.

The way it works now, if someone enters an invalid command, I display "INVALID"

The problem I'm having is with a string containing only spaces or only a single newline character.

Here is what I'm trying to do:

std::string command; // command user enters
getline(std::cin, command); // user input here

std::string tempCheck; // if we have a value in here other than empty, invalid
// use istringstream to grab the words, max of 3
std::istringstream parse{fullCommand}; // parse command into words

if(fullCommand.empty()){ // nothing has been input
    std::cout << "INVALID" << std::endl;
    return;
}

parse >> command; // stores first word (the command)
parse >> actionOne; // stores second word as parameter
parse >> actionTwo; // stores third word as parameter
parse >> tempCheck;

if(!tempCheck.empty()) {
    std::cout << "INVALID" << std::endl;
    return;
}

The variable tempCheck basically means that if it goes over three words (the limit I want for commands), then it is INVALID. I also thought that having an empty string would work, but it just ends up in an infinite loop when nothing is input, but I just hit enter.

Here is what I expect my input to be doing (bold is output):

CREATE username password
**CREATED**
      LOGIN          username password
**SUCCEEDED**
ASDF lol lol
**INVALID**

**INVALID**
REMOVE username
**REMOVED**

**INVALID**
QUIT
**GOODBYE**

Here is what is happening:

CREATE username password
**CREATED**
 // newline entered here

And it goes into a seemingly infinite loop. I can still type things, however, they don't actually affect anything. For example typing QUIT does nothing. But, if I restart my program and just type "QUIT" without trying to only use a newline character or only use a space, I get the expected output:

QUIT
**GOODBYE**

So, how do I tell either getline, or my istringstream, that if a user just enters a bunch of spaces and then hits enter, OR if the user just hits enter, display invalid and return? And is there anyway to do this with just getline or istringstream?

1

There are 1 answers

0
Simon Woo On

Alex, the following code may be helpful:

std::string strip(std::string const& s, std::string const& white=" \t\n")
{
    std::string::size_type const first = s.find_first_not_of(white);
    return (first == std::string::npos)
        ? std::string()
        : s.substr(first, s.find_last_not_of(white)-first+1);
}

You may apply it before creating the istringstream:

std::istringstream parse{strip(fullCommand)};

The above code was borrowed and slightly modified from the old well-known technique.