Wp3Dev
Wp3Dev

Reputation: 2079

Ending a loop when nothing is entered

Usually I write a control loop as follows: Loop that enters writes ints into vector nVec until "done" is entered.

while (cin >> sString){
    if (sString="done")
    { 
        break;
    }
    nVec.push_back(sString);

}

this works fine, but how would I go about doing this if I wanted the loop to end once the user entered nothing (just pressed enter)?

Upvotes: 0

Views: 2294

Answers (2)

Jcsq6
Jcsq6

Reputation: 489

It is actually possible to break when "nothing" is entered. You can do this using a stream_buf. Here's your code working as intended:

auto buff = std::cin.rdbuf();
while (true)
{
    // if a newline was entered
    if (buff->sgetc() == '\n')
    {
        // discard the newline
        buff->sbumpc();
        // get next character, if newline then quit
        if (buff->sgetc() == '\n')
        {
            buff->sbumpc();
            break;
        }
    }
    
    // read input into string
    std::cin >> sString;
    nVec.push_back(sString);
}

This code will wait for an empty newline is entered before it quits.

If you want all of your strings entered on one line, and it to break at the first newline then you can use the following code:

auto buff = std::cin.rdbuf();
while (buff->sgetc() != '\n')
{
    // read input into string
    std::cin >> sString;
    nVec.push_back(sString);
}

buff->sbumpc();

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477640

You can't "not enter anything" into your token-wise extraction. The only way for your loop to stop is for the user to send end-of-file (Ctrl-D on Linux). I would personally say that this is the correct behaviour, but if you want to end on empty input, you need to read lines:

Sales_item total;

for (std::string line; std::getline(std::cin, line); )
{
     if (line.empty()) { exit_program(); /* or "break" */ }

     std::istringstream iss(line);
     for (Sales_item book; iss >> book; )
     {
          total += book;
          std::cout << "The current total is " << total << std::endl;
     }
}

This way, you tokenize each line into possibly multiple books. If you just want one book per line, rip out the inner loop and just say std::istringstream(line) >> book;.

Upvotes: 1

Related Questions