1

Does using "else if" eliminate the need for breaks after each condition in a while loop? I want to exit out of the loop when one of the correct inputs has been entered.

The first version of my code looked like this

string s;
string str;
while (true) {
        cin >> s;
        if (s == "a") {
             str = "Apple";
             break;
        }
        if (s == "b") {
             str = "Banana";
             break;
        }
        ... more ifs ...
        else {
            cout << "Did not recognize input." << endl;
            continue;
        }
    }

Can I change it to the code below without negative consequence? It's much shorter and nicer-looking to me.

string s;
string str;
while (true) {
        cin >> s;
        if (s == "a") str = "Apple";
        else if (s == "b") str = "Banana";
        else if (s == "c") str = "Cat";
        ... more else-ifs ...
        else {
            cout << "Did not recognize input." << endl;
            continue;
        }
        break;
    }
user5759490
  • 113
  • 1
  • 9
  • 4
    If all the conditions are testing `s` for a single character string, it would be simpler, more maintainable, and more efficient to use `switch(s[0])` - or make `s` a `char` and then `switch(s)`. Even simpler perhaps would be to use a `std::map` or `std::map` to associate the `s` key with `str` strings. directly. – Clifford Mar 24 '16 at 22:55
  • Stylistically, I prefer the first one. A break at loop-scope looks plain wrong, since it defeats the purpose of the loop. Also: you need to test for `std::cin` in case of errors (`while (std::cin >> s)` is fine), and if you feel you are having too many branches, building a `std::map` beforehand as a lookup table will get you out of this mess. Also, a specific function doing the one-line parsing, returning a boolean as a success flag will likely be more readable. – Alexandre C. Mar 25 '16 at 08:32
  • @AlexandreC. A `break` at loop scope is *intended* to 'defeat the purpose of the loop'. Language features are what they are. Don't invent extra rules. – user207421 Mar 25 '16 at 08:34
  • @EJP: I don't get your point. When I see `while`, I expect a `break` statement to be a "special case", therefore inside a condition. This is a matter of taste, but when you read code, you expect to be surprised the least possible. – Alexandre C. Mar 25 '16 at 08:36
  • @Clifford the real code is a little more complicated, and not testing for single characters. I was trying to make the example as simple as possible. I am aware of switch statements but not sure when to use them over multiple ifs. Also, I will look into maps, they seem to be very useful for what I am trying to do. Thanks! – user5759490 Mar 25 '16 at 22:06

3 Answers3

3

Yes, that will work. The else if chain ensures that only the else case continues the loop, and not hitting the else case triggers a break.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Is one style more generally accepted than the other? – user5759490 Mar 24 '16 at 22:43
  • @user5759490: I'd find the single `break` and `continue` approach slightly more readable and slightly less error prone (no need to check each case for a `break`/`continue`). But Clifford's comment on the question offers even better options; a `switch` if they're all single character strings, or a `std::map` for lookup if not, would both be more performant, simpler and more maintainable. – ShadowRanger Mar 24 '16 at 23:27
1

Yes, you can.

Tip: if you want to be sure if a refactoring works you can write a test which checks if the code is correct.

Martin
  • 522
  • 4
  • 7
1

The code does the same thing, and regarding the execution time there is no difference, so they are similar. You don't need the last break though, in the first code snippet. However, if your thinking about a good styling for your case you should take into consideration the switch statement.

while(true){
   char c;
   cin >>c;

   switch (c) {
     case 'A': 
        // deal with char A
        break;
     case 'b':
        // deal with char b
        break;
     default:
        continue;
   }
     break;
}

For switch statements with strings you can check this: Evaluate a string with a switch in C++

I find switch statements more elegant.

Community
  • 1
  • 1
Ispas Claudiu
  • 1,890
  • 2
  • 28
  • 54