Can I use break to exit multiple nested 'for' loops?
Asked Answered
G

24

425

Is it possible to use the break function to exit several nested for loops?

If so, how would you go about doing this? Can you also control how many loops the break exits?

Gasiform answered 10/8, 2009 at 23:15 Comment(6)
Instead of using break or goto to exit multiple nested loops, you can enclose that particular logic in a function and use return to exit from multiple nested loops. This will maintain the aesthetics of your code and will prevent you from using goto which is a bad programming practice.Featherbrain
why goto is bad programming practice? it's widely used in kernel.Jennette
Goto statements reduces throughput of cpu pipelining. It makes branch prediction hard,Predispose
@Predispose so does any other statement that possibly exit the loop, whether is it goto, break, return... In practice this is not necessarily a big issue, as the branch that exits is executed only once after many executions of the branch that does not exit: any decent branch prediction algorithm will always predict the latter after a few iterations.Orifice
goto produces spaghetti code, which is hard to read and it is unnecessaryGilus
If you're confused why goto is bad because it legitimately makes your job easier/possible you are far more advanced than the typical programmer Dijkstra had in mind when writing "Goto Considered Harmful". Dijkstra wrote this letter for a 2nd year dev, shipping out unmaintainable spaghetti that could have been a few function calls and loops. He did not have kernel developers or ultra-small programs/ultra-slow machines or complex-algorithms that force loop-nesting in mind.Gaberlunzie
L
296

AFAIK, C++ doesn't support naming loops, like Java and other languages do. You can use a goto, or create a flag value that you use. At the end of each loop check the flag value. If it is set to true, then you can break out of that iteration.

Lissie answered 10/8, 2009 at 23:20 Comment(12)
Don't be afraid to use a goto if that is the best option.Heulandite
I'm a new C++ programmer (and one without any formal programming training) thus after reading about people's rants on goto. I'm hesitant on using it in fear my program might just suddenly explode and kill me. Other than that, when i used to write programs on my ti-83 (in boring math class of course), the functions the basic editor provided required the use of goto's.Gasiform
I seem to remember reading that many compilers give up on optimizing loops when a goto is present...Glyph
@Faken: Two types of programmers use goto: Bad programmers, and pragmatic programmers. The former are self explanatory. The latter, which you would fit into if you choose to use them well, use a so called "evil" concept when it is the lesser of (two) evils. Read this for a better understanding of some C++ concepts that you might need to use from time to time (macros, goto's, preprocessor, arrays): parashift.com/c++-faq-lite/big-picture.html#faq-6.15Heulandite
@Faken: There's nothing wrong with using goto. It's misusing a goto that is troublesome.Matrimony
@Hooked: That's right, except that using goto rarely ever is the best option. Why not put the loops into their own function (inline, if you're concerned about speed) and return from this?Frei
@sbi, sometime our functions have very big stack frame, and passing about 9-10+ vars will definetly make our code unreadable. Take a break and use goto, in this case it makes your program sexier and more readable. Some algorithms have sooo much control paths that makes goto more preferred way, especially state mashines in game loop - performance critical code where even a simple stack frame losses most or your performance!Ressler
@ПетърПетров inlined functions don't have a stack frameProlusion
inline is a compiler hint keyword, no guarantee it will inline the function. In any case, you write the code as though they were not inline which means passing variables.... I'm with @Петър Петров on that.Grouping
Unfortunately, I ended up seeing with my eyes how a stack frame was initialized on calling a inline function. Compiler have its final decision on that. The only really inlined thing is a macro. In fact, compiler will not even see it :) And DO NOT BOTHER throwing! It's like calling "goto" 10000 times in a row.Ressler
If the function manipulates 9-10+ variables within a loop, the performance penalty of that creation of the stack frame is absolutely negligible.Giff
Creating - and unwinding - a Stack Frame is more expensive than checking flag then performing a jump. if...goto very often gets compiled to to je or jne local jumps pair, while the call / ret function semantic often does far jumps and cache misses. So, don't be afraid to use goto it is is the smaller evil of twos. And, never truse inline if you want speed.Ressler
M
351

No, don't spoil it with a break. This is the last remaining stronghold for the use of goto.

Murr answered 10/8, 2009 at 23:24 Comment(11)
The MISRA C++ coding standard allows the use of goto to cover this exact kind of situation.Terefah
Real programmers are not afraid to use goto. Done it for 25 years -- no regrets -- saved a ton of development time.Diazomethane
I agree. gotos are a must if you do not have 8K pixels across, and need to call a sequence of 30 Windows OS calls.Burr
Or a simple "return" by putting the code in a function.Sniff
I came here looking for a way out of a switch statement inside a while loop. Logically, that's only one level of looping, but switch eats the break. This is the first goto I've written since I was writing in BASIC, circa 1985. (It's a very "hot" loop, even checking an extra boolean each time around costs 15-20%, so adding a done flag is not a good option. I just had to write this comment to cleanse my soul.)Susanasusanetta
I think it's a myth that using goto is bad. Also for the resulting machine code it's no difference if you use while, for, break, return or goto. It will all be translated into jumps...Earlap
Just keep in mind that a goto kills all optimizations by waiting for the CPU's cycles to flush what's still in its pipe by forcing the compiler to add nop ASM opcodes before the goto. In short: it is a performance killer.Remember
@Remember - but can a compiler implement an if/else without a JMP ?Murr
It's best never to assume what the compiler is going to do. It is true that a compiler can identify innumerable different patterns with a view to optimizing the code, but it is not for us to draw conclusions from them. First of all one compiler will behave differently from another but, in addition, the behavior of a compiler will change over time.Remember
ifs use branch instructions, which are optimized by the branch predictor.Gilus
20% for a bool flag? What loop would that be?Gilus
L
296

AFAIK, C++ doesn't support naming loops, like Java and other languages do. You can use a goto, or create a flag value that you use. At the end of each loop check the flag value. If it is set to true, then you can break out of that iteration.

Lissie answered 10/8, 2009 at 23:20 Comment(12)
Don't be afraid to use a goto if that is the best option.Heulandite
I'm a new C++ programmer (and one without any formal programming training) thus after reading about people's rants on goto. I'm hesitant on using it in fear my program might just suddenly explode and kill me. Other than that, when i used to write programs on my ti-83 (in boring math class of course), the functions the basic editor provided required the use of goto's.Gasiform
I seem to remember reading that many compilers give up on optimizing loops when a goto is present...Glyph
@Faken: Two types of programmers use goto: Bad programmers, and pragmatic programmers. The former are self explanatory. The latter, which you would fit into if you choose to use them well, use a so called "evil" concept when it is the lesser of (two) evils. Read this for a better understanding of some C++ concepts that you might need to use from time to time (macros, goto's, preprocessor, arrays): parashift.com/c++-faq-lite/big-picture.html#faq-6.15Heulandite
@Faken: There's nothing wrong with using goto. It's misusing a goto that is troublesome.Matrimony
@Hooked: That's right, except that using goto rarely ever is the best option. Why not put the loops into their own function (inline, if you're concerned about speed) and return from this?Frei
@sbi, sometime our functions have very big stack frame, and passing about 9-10+ vars will definetly make our code unreadable. Take a break and use goto, in this case it makes your program sexier and more readable. Some algorithms have sooo much control paths that makes goto more preferred way, especially state mashines in game loop - performance critical code where even a simple stack frame losses most or your performance!Ressler
@ПетърПетров inlined functions don't have a stack frameProlusion
inline is a compiler hint keyword, no guarantee it will inline the function. In any case, you write the code as though they were not inline which means passing variables.... I'm with @Петър Петров on that.Grouping
Unfortunately, I ended up seeing with my eyes how a stack frame was initialized on calling a inline function. Compiler have its final decision on that. The only really inlined thing is a macro. In fact, compiler will not even see it :) And DO NOT BOTHER throwing! It's like calling "goto" 10000 times in a row.Ressler
If the function manipulates 9-10+ variables within a loop, the performance penalty of that creation of the stack frame is absolutely negligible.Giff
Creating - and unwinding - a Stack Frame is more expensive than checking flag then performing a jump. if...goto very often gets compiled to to je or jne local jumps pair, while the call / ret function semantic often does far jumps and cache misses. So, don't be afraid to use goto it is is the smaller evil of twos. And, never truse inline if you want speed.Ressler
N
129

Just to add an explicit answer using lambdas:

  for (int i = 0; i < n1; ++i) {
    [&] {
      for (int j = 0; j < n2; ++j) {
        for (int k = 0; k < n3; ++k) {
          return; // yay we're breaking out of 2 loops here
        }
      }
    }();
  }

Of course this pattern has a certain limitations and obviously C++11 only but I think it's quite useful.

Naples answered 16/10, 2015 at 15:56 Comment(7)
This might confuse the reader into thinking the return causes the function the lambda is in to return, and not the lambda itself.Mucous
@Xunie: If your loop is so complicated, that you forget that you are in a lambda, it is time to put them in a different function, but for simple cases, this should work quite well.Enamour
You can capture the lambda in a RIIA template that gives it a name and calls it in dtor(aka scope gaurd). This would not add any performance gain but can improve readabilty and reduce the risk of missing the function call parenthesis.Virus
this solution is not working when you also want a real return inside the loop... I mean: at one condition you just want to break out of 2 loops. at another condition you want to return out of the function. BTW: I really like this way of thinking! +1!Cruck
I tested this on godbolt and it appears to compile to identical code to using a goto! Another advantage of this solution over goto is that labels only work if they label a statement. For example, you can't write my_label: }Grano
How this is called? First time to see it in code.Jennette
lambdas are not debugger friendly.Affianced
B
63

Another approach to breaking out of a nested loop is to factor out both loops into a separate function, and return from that function when you want to exit.

Of course, this brings up the other argument of whether you should ever explicitly return from a function anywhere other than at the end.

Bellwort answered 10/8, 2009 at 23:39 Comment(4)
That's a C problem. With RIAA early return is not a problem as all the problems associated with early return are correctly handled.Chocolate
I understand that proper application of RIAA can solve the resource cleanup problem in C++, but I have seen the philosophical argument against early return continue in other environments and languages. One system I worked on where the coding standard prohibited early return had functions littered with boolean variables (with names like continue_processing) that controlled the execution of blocks of code further down in the function.Bellwort
What is RIAA? Is that anything like RAII? =DHeulandite
Depends how many for loops he's got and how deep the nest goes... do you want the blue pill or the red pill?Grouping
E
38

break will exit only the innermost loop containing it.

You can use goto to break out of any number of loops.

Of course goto is often Considered Harmful.

is it proper to use the break function[...]?

Using break and goto can make it more difficult to reason about the correctness of a program. See here for a discussion on this: Dijkstra was not insane.

Ephemeron answered 10/8, 2009 at 23:20 Comment(6)
A good answer in that it explains that "goto is harmful" meme is strongly tied to the more generalized "control flow interruption is harmful" statement. It is meaningless to say "goto is harmful", and then turn around and recommend using break or return.Outlier
@Pavel: break and return have the advantage over goto that you don't need to hunt for a label in order to find where they go. Yes, underneath they are some kind of goto, but a very restricted one. They are a lot easier to decipher by a programmer's pattern-matching brain than the unrestricted goto. So IMO they are preferable.Frei
@sbi: True, but break is still not part of structured programming. It is just better tolerated than a goto.Heulandite
@KarlVoigtland the Dijkstra link is outdated; this appears to be working: blog.plover.com/2009/07Adenectomy
There is absolutely nothing wrong with using goto in this situation. A well placed goto is leaps and bounds better and more readable than many of the contorted solutions otherwise proposed.Definiens
I'd argue that C++'s "goto after_loop;" is so straightforward it's easier to understand than Java's "break before_loop;". I don't find it particularly elegant to quit a loop by referring to a label that's declared before the actual loop. I know the label is supposed to give the loop a name, but I never managed to like it. What if you put other statements between the label and the loop? Is that a syntax error to try to break? Same for continue statements.Lasley
R
36

How about this?

for(unsigned int i=0; i < 50; i++)
{
    for(unsigned int j=0; j < 50; j++)
    {
        for(unsigned int k=0; k < 50; k++)
        {
            //Some statement
            if (condition)
            {
                j=50;
                k=50;
            }
        }
    }
}
Rendarender answered 30/3, 2012 at 15:37 Comment(1)
interesting approach but I definitely like the way ered @inf.ig.sh handles it. for (unsigned int y = 0; y < y_max && !gotoMainLoop; y++).Ellene
K
24

A code example using goto and a label to break out of a nested loop:

for (;;)
  for (;;)
    goto theEnd;
theEnd:
Kenn answered 10/3, 2015 at 23:11 Comment(0)
S
23

Although this answear was already presented, i think a good approach is to do the following:

for(unsigned int z = 0; z < z_max; z++)
{
    bool gotoMainLoop = false;
    for(unsigned int y = 0; y < y_max && !gotoMainLoop; y++)
    {
        for(unsigned int x = 0; x < x_max && !gotoMainLoop; x++)
        {
                          //do your stuff
                          if(condition)
                            gotoMainLoop = true;
        }
    }

}
Stander answered 3/11, 2011 at 8:27 Comment(3)
which is good but still not so readable, i'd prefer goto in that caseRessler
this makes your code "quite" slow because the gotoMainLoop is checked every cycleCruck
In this case, using the real goto makes core more readable and better-performing.Ressler
K
14

I know this is an old thread but I feel this really needs saying and don't have anywhere else to say it. For everybody here, use goto. I just used it.

Like almost everything, goto is not 100% either/xor "bad" or "good". There are at least two uses where I'd say that if you use a goto for them - and don't use it for anything else - you should not only be 100% okay, but your program will be even more readable than without it, as it makes your intention that much clearer (there are ways to avoid it, but I've found all of them to be much clunkier):

  1. Breaking out of nested loops, and
  2. Error handling (i.e. to jump to a cleanup routine at the end of a function in order to return a failure code and deallocate memory.).

Instead of just dogmatically accepting rules like "so-so is 'evil'", understand why that sentiment is claimed, and follow the "why", not the letter of the sentiment. Not knowing this got me in a lot of trouble, too, to the point I'd say calling things dogmatically "evil" can be more harmful than the thing itself. At worst, you just get bad code - and then you know you weren't using it right so long as you heard to be wary, but if you are wracking yourself trying to satisfy the dogmatism, I'd say that's worse.

Why "goto" is called "evil" is because you should never use it to replace ordinary ifs, fors, and whiles. And why that? Try it, try using "goto" instead of ordinary control logic statements, all the time, then try writing the same code again with the control logic, and tell me which one looks nicer and more understandable, and which one looks more like a mess. There you go. (Bonus: try and add a new feature now to the goto-only code.) That's why it's "evil", with suitable scope qualification around the "evil". Using it to short-circuit the shortcomings of C's "break" command is not a problematic usage, so long as you make it clear from the code what your goto is supposed to accomplish (e.g. using a label like "nestedBreak" or something). Breaking out of a nested loop is very natural.

(Or to put it more simply: Use goto to break out of the loop. I'd say that's even preferable. Don't use goto to create the loop. That's "evil".)

And how do you know if you're being dogmatic? If following an "xyz is evil" rule leads your code to be less understandable because you're contorting yourself trying to get around it (such as by adding extra conditionals on each loop, or some flag variable, or some other trick like that), then you're quite likely being dogmatic.

There's no substitute for learning good thinking habits, moreso than good coding habits. The former are prior to the latter and the latter will often follow once the former are adopted. The problem is, however, that far too often I find, the latter are not explicated enough. Too many simply say "this is bad" and "this needs more thought" without saying what to think, what to think about, and why. And that's a big shame.

(FWIW, in C++, the need to break out of nested loops still exists, but the need for error codes does not: in that case, always use exceptions to handle error codes, never return them unless it's going to be so frequent that the exception throw and catch will be causing a performance problem, e.g. in a tight loop in a high demand server code, perhaps [some may say that 'exceptions' should be 'used rarely' but that's another part of ill-thought-out dogmatism: no, at least in my experience after bucking that dogma I find they make things much clearer - just don't abuse them to do something other than error handling, like using them as control flow; effectively the same as with "goto". If you use them all and only for error handling, that's what they're there for.].)

Katlin answered 24/7, 2020 at 0:49 Comment(0)
P
13

One nice way to break out of several nested loops is to refactor your code into a function:

void foo()
{
    for(unsigned int i=0; i < 50; i++)
    {
        for(unsigned int j=0; j < 50; j++)
        {
            for(unsigned int k=0; k < 50; k++)
            {
                // If condition is true
                return;
            }
        }
    }
}
Percyperdido answered 12/6, 2013 at 4:0 Comment(6)
...which is not a option if we have to pass 10-20 variables for stack framing this function.Ressler
@ПетърПетров then go for a lambda which is also better as you can define it exactly where you need it.Deprived
+1 for lambdas but overhaul in game engine core where even one stack frame is still a bottleneck. Sorry to tell, but lambdas are not so lightweight at least in MSVC 2010.Ressler
@ПетърПетров Then change the pair of functions into a class, and the stack variables into private members.Uchida
This only overcomplicates the already complex code :) Sometimes, goto is the only solution. Or if you write complex automata with "goto state X" documentation, then goto is actually making the code read as written in the document. Also, C# and go both have goto with a purpose: no language is turing-complete without a goto, and gotos are often the best used tools for writing intermediate translator or assembly-like code.Ressler
@ПетърПетров If you have to pass 20 stack variables I'd argue there are bigger problems than the choice of return vs. goto.Detinue
G
9

I'm not sure if it's worth it, but you can emulate Java's named loops with a few simple macros:

#define LOOP_NAME(name) \
    if ([[maybe_unused]] constexpr bool _namedloop_InvalidBreakOrContinue = false) \
    { \
        [[maybe_unused]] CAT(_namedloop_break_,name): break; \
        [[maybe_unused]] CAT(_namedloop_continue_,name): continue; \
    } \
    else

#define BREAK(name) goto CAT(_namedloop_break_,name)
#define CONTINUE(name) goto CAT(_namedloop_continue_,name)

#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y

Example usage:

#include <iostream>

int main()
{
    // Prints:
    // 0 0
    // 0 1
    // 0 2
    // 1 0
    // 1 1

    for (int i = 0; i < 3; i++) LOOP_NAME(foo)
    {
        for (int j = 0; j < 3; j++)
        {
            std::cout << i << ' ' << j << '\n';
            if (i == 1 && j == 1)
                BREAK(foo);
        }
    }
}

Another example:

#include <iostream>

int main()
{
    // Prints: 
    // 0
    // 1
    // 0
    // 1
    // 0
    // 1

    int count = 3;
    do LOOP_NAME(foo)
    {
        for (int j = 0; j < 3; j++)
        {
            std::cout << ' ' << j << '\n';
            if (j == 1)
                CONTINUE(foo);
        }
    }
    while(count-- > 1);
}
Grum answered 26/4, 2020 at 22:30 Comment(10)
This is the most brilliant thing I've seen in this threadDolomite
Although, it seems to let the outer loop to finish its current routine. It also doesn't directly "jump over" multiple levels of nested loops.Dolomite
@Dolomite Can you show an example of the wrong behavior? Seems to work correctly for me.Grum
Nevermind, I tested it and it works perfectly indeed. However, an explanation on how it works would be useful :)Dolomite
@Dolomite There's not much to see here, once you expand the macros and look at the result. The loop body becomes if (false) {...} else {/*original loop body*/}, where the first branch that's never taken contains a few goto labels, that BREAK and CONTINUE jump to.Grum
Totally worth it! Very nice. Thanks.Waterish
Question: Does the if statement really need to declare a variable? My experiments suggest it could be simplified to if (0) { ....Waterish
@Waterish The variable is needed to stop you from using break/continue outside of this loop. The compiler refuses to goto into a scope if it requires creating a new variable, allowing you to break/continue only inside this if-else block.Grum
@Waterish FYI, the best place to try out formatting is this.Grum
have an upvote 🤣Birdie
C
7

goto can be very helpful for breaking nested loops

for (i = 0; i < 1000; i++) {
    for (j = 0; j < 1000; j++) {
        for (k = 0; k < 1000; k++) {
             for (l = 0; l < 1000; l++){
                ....
                if (condition)
                    goto break_me_here;
                ....
            }
        }
    }
}

break_me_here:
// Statements to be executed after code breaks at if condition
Chibouk answered 27/9, 2016 at 14:57 Comment(0)
U
4

I do think a goto is valid in this circumstance:

To simulate a break/continue, you'd want:

Break

for ( ;  ;  ) {
    for ( ;  ;  ) {
        /*Code here*/
        if (condition) {
            goto theEnd;
        }
    }
}
theEnd:

Continue

for ( ;  ; ) {
    for ( ;  ;  ) {
        /*Code here*/
        if (condition) {
            i++;
            goto multiCont;
        }
    }
    multiCont:
}
Unto answered 27/11, 2015 at 9:58 Comment(2)
"Continue" will not work there, because the iteration expression of the first loop won't be executedBearcat
I'm assuming that the iterator for the first loop is i. Hence i++ before the gotoUnto
T
3

The break statement terminates the execution of the nearest enclosing do, for, switch, or while statement in which it appears. Control passes to the statement that follows the terminated statement.

from msdn.

Tripinnate answered 10/8, 2009 at 23:19 Comment(0)
M
2

My suggestion is use a check variable to break a desired loop. The result code may not be so pleasant.
You can use preprocessors in order to make desired breaking under the hood. This approach can hides ugly codes and extra complexity.
For example, I created my custom break mechanism as follow:

Wanted code:

for (int i = 0; i < 100; i++) {
    for (int j = 0; j < 100; j++) {
        for (int k = 0; k < 100; k++) {
            //do something
            if (desiredCondition) {
                breakToLevel = 0;
            }
            if (breakToLevel < 3) {
                break;
            }
        }
        if (breakToLevel < 2) {
            break;
        }
    }
    if (breakToLevel < 1) {
        break;
    }
}

Defined macros:

#define BREAK_TO(L) breakToLevel = (L); 
#define CHECK_BREAK(L) if (breakToLevel < (L)) break; 

and result:

for (int i = 0; i < 100; i++) {
    for (int j = 0; j < 100; j++) {
        for (int k = 0; k < 100; k++) {
            //do something
            if (desiredCondition) {
                BREAK_TO(0)
            }
            CHECK_BREAK(3)
        }
        CHECK_BREAK(2)
    }
    CHECK_BREAK(1)
}
Malaco answered 9/7, 2022 at 9:55 Comment(0)
K
1

Break any number of loops by just one bool variable see below :

bool check = true;

for (unsigned int i = 0; i < 50; i++)
{
    for (unsigned int j = 0; j < 50; j++)
    {
        for (unsigned int k = 0; k < 50; k++)
        {
            //Some statement
            if (condition)
            {
                check = false;
                break;
            }
        }
        if (!check)
        {
            break;
        }
    }
    if (!check)
    {
        break;
    }
}

In this code we break; all the loops.

Karole answered 17/7, 2019 at 11:46 Comment(0)
A
0

Other languages such as PHP accept a parameter for break (i.e. break 2;) to specify the amount of nested loop levels you want to break out of, C++ however doesn't. You will have to work it out by using a boolean that you set to false prior to the loop, set to true in the loop if you want to break, plus a conditional break after the nested loop, checking if the boolean was set to true and break if yes.

Agrobiology answered 10/8, 2009 at 23:23 Comment(0)
E
0

I know this is old post . But I would suggest a bit logical and simpler answer.

for(unsigned int i=0; i < 50; i++)
    {
        for(unsigned int j=0; j < conditionj; j++)
        {
            for(unsigned int k=0; k< conditionk ; k++)
            {
                // If condition is true

                j= conditionj;
               break;
            }
        }
    }
Epigrammatize answered 30/5, 2016 at 7:57 Comment(1)
That's not very scalable solution as j = conditionj won't work if you have a complex predicate instead of j < conditionj.Deerhound
O
0
 bool found = false;
    
    for(int i=0; i < m; ++i){
        for(int j=0; j < n; ++j)
            if(grid[i][j] == '*'){
                q.push(make_pair(i,j));
                found = true;
                break;
            }
        if(found)
            break;
    }
Opia answered 15/3, 2022 at 3:58 Comment(0)
V
0

you can use "goto" to leave nested loops below is my original code including "goto"

int main()
{
    string str;
    while (cin >> str)
    {
        if (str == "0")
            break;
        int sum = 0;
        for (auto ch : str)
        {
            if (ch <= 'z' && ch >= 'a')
                sum += (ch - 'a' + 1);
            else if (ch >= 'A' && ch <= 'Z')
                sum += (ch - 'A' + 1);
            else
            {
                cout << "Fail" << endl;
                goto fail;
            }
        }

        cout << sum << endl;
        fail:
    }
    return 0;
}

however, I could avoid "goto" by adding a function "calculate"

void calculate(const string &str)
{
    int sum = 0;
    for (auto ch : str)
    {
        if (ch <= 'z' && ch >= 'a')
            sum += (ch - 'a' + 1);
        else if (ch >= 'A' && ch <= 'Z')
            sum += (ch - 'A' + 1);
        else
        {
            cout << "Fail" << endl;
            return;
        }
    }

    cout << sum << endl;
}

int main()
{
    string str;
    while (cin >> str)
    {
        if (str == "0")
            break;
        calculate(str);
    }
    return 0;
}
Vanya answered 15/12, 2022 at 18:7 Comment(0)
C
0

The most graceful way is to use exception.

Exception means encountering an abnormal situation, which can not only be a too bad situation but also be a too good situation.

For example you are looking for an element in a 3d array with 3 nested for-loops. The normal situation is "The current is NOT the one I'm looking for". The abnormal situation is "The current IS the one".

Remember the difference between error and exception. An exception doesn't have to be an error, it can be a good news.

Calamite answered 1/7, 2023 at 10:16 Comment(0)
S
-1
  while (i<n) {
    bool shouldBreakOuter = false;
    for (int j=i + 1; j<n; ++j) {
      if (someCondition) {
          shouldBreakOuter = true;
      }
    }

    if (shouldBreakOuter == true)
      break;

  }
Snodgrass answered 21/10, 2017 at 15:37 Comment(0)
C
-2

You can use try...catch.

try {
    for(int i=0; i<10; ++i) {
        for(int j=0; j<10; ++j) {
            if(i*j == 42)
                throw 0; // this is something like "break 2"
        }
    }
}
catch(int e) {} // just do nothing
// just continue with other code

If you have to break out of several loops at once, it is often an exception anyways.

Culp answered 2/4, 2013 at 14:49 Comment(7)
I would like to know the reason why this answer get this much down-votes.Hedelman
@Hedelman The solution has down votes because it's using an exception to control the execution flow. As the name suggests, exceptions should only be used on exceptional cases.Kenn
@HelioSantos Isn't this an exceptional situation for which the language is not supplying proper solution?Hedelman
It would be valid if 1. my program is compiled with exceptions support (never in my case) and 2. it really WAS an exception 3. You are willing to put up with the horrific overhead.Ribbentrop
The performance impact of the throw is huge for something that is not an unrecoverable error 99% of the time.Burr
@hkbattousai The language does provide solutions, such as using a a test condition, or using a goto.Burr
Also, if another exception was thrown from that code block, you would catch it, thinking it is the control flow one and it would get propagated/handled properly.Batruk
L
-6

Breaking out of a for-loop is a little strange to me, since the semantics of a for-loop typically indicate that it will execute a specified number of times. However, it's not bad in all cases; if you're searching for something in a collection and want to break after you find it, it's useful. Breaking out of nested loops, however, isn't possible in C++; it is in other languages through the use of a labeled break. You can use a label and a goto, but that might give you heartburn at night..? Seems like the best option though.

Logistics answered 10/8, 2009 at 23:20 Comment(1)
It's not strange at all. If you're iterating over a collection to look for something (and don't have a faster way of searching), there's no point finishing the loop. (as one example)Vivian

© 2022 - 2025 — McMap. All rights reserved.