While loop within a while loop, how to both conditions work? - c++

I am writing a program that involves reading numerous bits of data from files, and I have ran into a bit of a dilemma (being a relatively inexperienced programmer). If a while loop is contained within another while loop, which conditions need to be fulfilled in order to leave the loop?
My specific situation is shown below, (emptyLineFound is a Boolean set to be true when empty line has been found)
while(!file.eof()) {
....
while(!emptyLineFound) {
....
}
}
Which condition takes priority? Must they both be satisfied to leave that section of code? e.g if it is at the end of the file and an empty line can not be found as there is no line, will it mess up?

Both sections do not have to be satisfied for the nested while to exit.
while(!file.eof()) {
Will continue to run while the file is not at the end of the stream.
while(!emptyLineFound) { .... }
Will continue to run while an empty line is not found.
Once an empty line is found, you will drop out of the nested loop and the parent loop will continue until the condition is satisfied (EOF is reached).

While(ExitCondition)
{
// you are at this point if ExitCondition fails .
while(another-ExitCondition)
{
// you are at this point if another-ExitCondition fails
}
// you will come at this point once another-ExitCondition becomes true
}
// you will be at this point once ExitCondition becomes true .

In your question, the inner loop will end when emptyLineFound is true. The outer loop will continue until file.eof() is true. Presumably something in the inner loop sets emptyLineFound to false before the next loop.
Note that the conditions are tested as the code gets there, so, in theory you could have something like this:
while(!file.eof())
{
while(!emptyLineFound)
{
... do some reading ...
if (file.eof())
{
... reset file so we can do more reading ...
}
}
}
and the loop would continue forever, except if file.eof() is true from the very beginning of the loop.
By the way, in general, using !file.eof() as a loop control is a pretty poor idea. It is much better to use the read operation itself, e.g. while (file >> var) ... - since while (!file.eof()) tends to lead to an extra iteration, because file.eof() isn't true until you have read PAST the end.

Each time the outer loop is repeated, the inner loops are reentered and start new.

Perhaps the code becomes clear if expressed differently:
void f()
{
// ...
while (!file.eof()) {
// ...
}
}
int main()
{
// ...
while (!emptyLineFound) {
f();
}
}
This is semantically the same as your program; it has the same overall logic.
From here, you can clearly see that a call to f() will not terminate until f.eof() is true, and that main will repeatedly call f() (and thus perform the "inner" loop) until emptyLineFound is true.

Related

Use of goto in this very specific case... alternatives?

I have a question about the possibile use of goto in a C++ code: I know that goto shall be avoided as much as possibile, but in this very particular case I'm having few difficulties to find good alternatives that avoid using multiple nested if-else and/or additional binary flags...
The code is like the following one (only the relevant parts are reported):
// ... do initializations, variable declarations, etc...
while(some_flag) {
some_flag=false;
if(some_other_condition) {
// ... do few operations (20 lines of code)
return_flag=foo(input_args); // Function that can find an error, returning false
if(!return_flag) {
// Print error
break; // jump out of the main while loop
}
// ... do other more complex operations
}
index=0;
while(index<=SOME_VALUE) {
// ... do few operations (about 10 lines of code)
return_flag=foo(input_args); // Function that can find an error, returning false
if(!return_flag) {
goto end_here; // <- 'goto' statement
}
// ... do other more complex operations (including some if-else and the possibility to set some_flag to true or leave it to false
// ... get a "value" to be compared with a saved one in order to decide whether to continue looping or not
if(value<savedValue) {
// Do other operations (about 20 lines of code)
some_flag=true;
}
// ... handle 'index'
it++; // Increse number of iterations
}
// ... when going out from the while loop, some other operations must be done, at the moment no matter the value of some_flag
return_flag=foo(input_args);
if(!return_flag) {
goto end_here; // <- 'goto' statement
}
// ... other operations here
// ... get a "value" to be compared with a saved one in order to decide whether to continue looping or not
if(value<savedValue) {
// Do other operations (about 20 lines of code)
some_flag=true;
}
// Additional termination constraint
if(it>MAX_ITERATIONS) {
some_flag=false;
}
end_here:
// The code after end_here checks for some_flag, and executes some operations that must always be done,
// no matter if we arrive here due to 'goto' or due to normal execution.
}
}
// ...
Every time foo() returns false, no more operations should be executed, and the code should execute the final operations as soon as possible. Another requirement is that this code, mainly the part inside the while(index<=SOME_VALUE) shall run as fast as possible to try to have a good overall performance.
Is using a 'try/catch' block, with the try{} including lots of code inside (while, actually, the function foo() can generate errors only when called, that is in two distinct points of the code only) a possibile alternative? Is is better in this case to use different 'try/catch' blocks?
Are there other better alternatives?
Thanks a lot in advance!
Three obvious choices:
Stick with goto
Associate the cleanup code with the destructor of some RAII class. (You can probably write it as the delete for a std::unique_ptr as a lambda.)
Rename your function as foo_internal, and change it to just return. Then write the cleanup in a new foo function which calls foo_internal
So:
return_t foo(Args...) {
const auto result = foo_internal(Args..);
// cleanup
return result;
}
In general, your function looks too long, and needs decomposing into smaller bits.
One way you can do it is to use another dummy loop and break like so
int state = FAIL_STATE;
do {
if(!operation()) {
break;
}
if(!other_operation()) {
break;
}
// ...
state = OK_STATE;
} while(false);
// check for state here and do necessary cleanups
That way you can avoid deep nesting levels in your code beforehand.
It's C++! Use exceptions for non-local jumps:
try {
if(some_result() < threshold) throw false;
}
catch(bool) {
handleErrors();
}
// Here follows mandatory cleanup for both sucsesses and failures

C++ Will all code inside a nested 'if' statement run, even if that changes the boolean value of the outside statement?

I have a couple of if statements in my C++ code (one nested inside the other), and I want to be sure that they will run as I expect- the code is:
if(state == entry){
if(abs(distance < 0.05){
state = arcing;
...
startAngle = positionAC;
}
// Some more statements here...
}
If the second if statement condition is met, will the code where my comment "// Some more statements here..." be run now that the value of state has changed to arcing rather than entry? I would have thought that they should be run because the code will still be executing from when the first condition was true, even though it now no longer will be. Is this correct?
The if-check
if(state == entry)
will be performed exactly once, at the moment that line is reached in the code.
From then on, it doesn't matter if the values of state or entry are modified - the entirety of the code inside the if-block will be executed, if state was equal to entry when that line was reached.
Yes. I remember once having this doubt about the Pascal while loop. The text book we had didn't describe the workings of the loop in very concrete terms, but only that it iterated “while” the condition was true. Some experimentation convinced me that the condition was only checked once per iteration, namely at the start of the loop. But the thing is, I should not have had to check that: the book should have been clear on that.
So, clarity:
A C++ if statement like
if( condition )
{
action_1;
action_2;
action_3;
}
something_more;
is 1equivalent to:
const bool do_it = condition; // The single evaluation of condition
if( do_it ) goto do_actions;
goto do_more_things;
do_actions: // Just a name for this place in the code, a "label".
action_1;
action_2;
action_3; // The next executed statement is something_more.
do_more_things:
something_more;
And yes, both are valid C++ code.
1) This equivalence ignores possible name collisions, and it assumes that none of the actions are declarations. Declarations can foil the equivalence in two ways. First, it's not permitted to goto-jump over a declaration that executes initialization and that's in scope at the point jumped to. Second, destructors are executed when the execution leaves a block, and to capture that one has to imagine that those destructor executions are among the actions.
If the condition in the if statement
if(state == entry){
will be evaluated to true (it is evaluated only once in this point) then the compound statement of the if will be executed.
The statements under the comment will be executed exactly once, unless the first condition itself is NOT within a loop, or a method which is called recursively.
But if you want to make sure that the code after the comment is executed only when the state == entry at that point of time you can change your code as below
if((state == entry) && (abs(distance < 0.05)) {
state = arcing;
...
startAngle = positionAC;
}
else if (state == entry)
{
// Some more statements here...
}

Two for loops and an if statement inside it

My code is something like this:-
for() //outer for
{
for() //inner for
{
if()
{
break;
}
}
}
If the break statement executes the next execution will be of which for loop?
I know this is a very abstract question but I really don't have time to write the full code. Thanks.
break will break the inner for **loop** only. It breaks the closest loop ONLY where it was called.
In your example, if your if condition is satisfied, it will stop iterations of the inner for loop and move back(continue) the outer for loop.
The break statement terminates the execution of the nearest enclosing do, for, switch, or while statement in which it appears. In this case, that means breaking out of the inner for only.
Edit: Standard Reference: 6.6.1 The break statement [stmt.break]
1 The break statement shall occur only in an iteration-statement or a
switch statement and causes termination of the smallest enclosing
iteration-statement or switch statement; control passes to the
statement following the terminated statement, if any.
You can use goto to break the outer loop as well if you like.
You'll need a way to break the outer loop as the break will only leave its enclosing scope. What you use to manage state can be anything, but in its most simple form you can just use a boolean and check for that as well as your original condition in the outermost loop.
bool breakLoop = false;
for(...; ... && !breakLoop; ...) //outer for
{
for() //inner for
{
if()
{
breakLoop = true;
break;
}
}
}

Weirdest C++ stack empty() fault

My program crashes because it reaches a stack.top() it shouldn't reach, as the stack is empty.
I have an if which checks just that:
if(!st.empty());
//do stuff
(I have initialized
stack<int> st;
).
But although I can see in the debug that the stack is empty, it still goes in the if!
I even wrote this code:
if(st.size()>0);
cout<<st.size();
And it prints 0!
What is going on and how can I fix it? Thanks!
The semicolons after the if statements are the problem
BAD:
if(st.size()>0); // <-- this should not be here!!!!!!!!
cout<<st.size();
Properly rewritten:
if(st.size()>0) {
cout<<st.size();
}
Also, as #WhozCraig pointed out, the other statement has a semicolon too!
BAD:
if(!st.empty()); // <--BAD!
//do stuff
Good:
if(!st.empty()) {
//do stuff
}
ALWAYS!! use brackets with branches (if, switch), and loops (for, while, do-while)!!! It pays off big time! (Not to mention, a cute kitten dies each and every time such a block is written without brackets!) ALWAYS!!
For example this can kill a day in debugging:
BAD:
int i=0;
...
while(i++<1000);
doStuff(i);
Good:
int i=0;
...
while(i++<1000) {
doStuff(i);
}
Beware (as #WhozCraig pointed out again) this does not automagically solve the problem of semicolon terminated branch and loop statements, as this is perfectly valid syntax:
if (condition);{ ...code... }
Or
if (condition);
{
...code...
}
But in my opinion and experience (this is totally subjective!) - as I myself have fallen into this trap a couple of times - I experienced that when I have the curly bracket after the aforementioned statements, I didn't ever make the mistake of typing a semicolon again. Adhering to this convention was a silver bullet - for me, and others could benefit from this too. Also, if there was a semicolon there, it would immediately catch my eye, just by looking, as it is an "uncommon pattern of characters".
There is no "in the if", as your if contains only an empty statement:
if(!st.empty());
//do stuff -- that's outside the if!!!!
(Background: The syntax is if (condition) block, with block being either a statement or a block of statements. ; is an empty statement, so if (...) ; means "if condition fulfilled then do nothing" -- which probably never is what you have in mind.)
You should write
if(!st.empty()) {
//do stuff -- now it's inside!
}
Be careful! Do NOT write
if(!st.empty()); // notice the semicolon making it wrong; without the semicolon it would be ok
{
// outside again
}

Why use do { ... } while (FALSE); in C++ outside of macros [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Are do-while-false loops common?
Is there a reason to have code like:
do {
// a lot of code that only needs to be run once
} while (FALSE);
when the code isn't defining a macro? I know it's a trick when it comes to macros, but is there a reason for it in normal code?
Well, it does allow you to use the break; (or continue) keyword for early exit if you have a need for that for some reason. That would be kinda ugly though. I'd really rather see it moved into its own routine, with the early exit implemented via a return; statement.
Well one reason for it would be if you want to break out at some point.
i.e.
do
{
//some code that should always execute...
if ( condition )
{
//do some stuff
break;
}
//some code that should execute if condition is not true
if ( condition2 )
{
//do some more stuff
break;
}
//further code that should not execute if condition or condition2 are true
}
while(false);
In certain situations the resulting code is a little bit more clear / easier to understand if written as above.
Such a construct is used as a kind of goto to be able to jump after the end of the loop using a break statement inside.
I would not do this but:
I looks slightly more logical than just braces
int main()
{
{
std::ifstream file("Data");
// DO STUFF
} // Data now closed.
// LOTS OF STUFF SO YOU CANT SEE file2 below.
// We can re-use data here as it was closed.
std::ofstream file2("Data");
// DO STUFF
}
An unobservant maintainer may see the braces and think.
What the heck and remove them
int main()
{
std::ifstream file("Data");
// DO STUFF
// LOTS OF STUFF SO YOU CANT SEE file2 below.
// FAIL. data is still open from before.
std::ofstream file2("Data");
// DO STUFF
}
I suppose using the while tick at least make syou think about it (though an unobservant maintainer may still remove it).
int main()
{
do
{
std::ifstream file("Data");
// DO STUFF
} while (false);
// LOTS OF STUFF SO YOU CANT SEE file2 below.
// We can re-use data here as it was closed.
std::ofstream file2("Data");
// DO STUFF
}
There is no reason to ever write a loop that is known, at compile time, to execute exactly once.
Doing so, in order to pretend that goto is written as break, is abusive.
EDIT:
I've just realised that my assertion about compile-time knowledge is false: I suppose you might do something complicated with conditional #defines that might mean that, at compile time for one build configuration, it is known to execute once, but for a different build configuration, it is executed multiple times.
#ifdef SOMETHING
#define CONDITION (--x)
#else
#define CONDITION 0
#endif
...
int x = 5
do{
...
} while(CONDITION)
However, the spirit of my assertion still stands.
It can be used to implement a behavior similar to goto statement, or say jump behavior!
See this:
do
{
if (doSomething() != 0) break; //jump
if (doSomethingElse() != 0) break; //jump
...
if (doSomethingElseNew() != 0) break; //jump
} while(false);
//if any of the break encountered, execution can continue from here, just after the do-while block!
// statement1
// statement2
// statement3
// so on
Taken from here: Are do-while-false loops common?