for (int att = 1; att < 11; att++)
{
<body>;
//break will completely finish running the program
}
I'm making a CodeBreaker(Mastermind) game, and I'm having trouble with ending a loop earlier than it needs to at less than 11, and then set the loop back to the initialization state of att = 1.
att stands for "attempts". The user can guess a randomly generated code up to a maximum of 10 times. Once the user guesses the correct code in less than 10 attempts, I want to prompt the user to play again and generate a new random code. But the loop shown above is still running.
How can I end the loop early, but still continue running the program? Majority of the program depends on this one loop, so break will completely stop it running.
To set the loop back to the initialization state of att = 1, you can use continue:
for (int att = 1; att < 11; att++)
{
if(you_want_to_set_loop_back) {
att = 1;
continue; //It will begin the loop back with att=1, but if any other variable is modified, they will remain as it is (modified).
}
}
OR
You can write your loop in a function with all the variable that you want at their initial value. And keep calling this function as long as you want. To break out the loop, use break and return from function or directly return from the loop instead of breaking it.
You could do something like:
while(true){
for (int att = 1; att < 11; att++)
{
<body>;
//game, and when it finishes
break;
}
//Asks player if he wants to continue, if not then break again
}
How about a while-loop around the for-loop?
while(programRunning){
for (int att = 1; att < 11; att++)
{
<body>;
if(answer==correct){
att = 12; // ends the for-loop
}
}
if(gameOver){
programRunning = false; // unless you want to end the game, starts the for-loop from att = 1
}
}
I think you might try in following way:
bool bQuitGame = false;
while(!bQuitGame)
{
for(att = 1; att < 10; ++att)
{
if(you want to only quit "for" but stay in "while")
{
<code...>
break;
}
else if(you want to quit "while")
{
<code...>
bQuitGame = true;
break
}
else if(you want to start the next iteration in "for")
{
<code..>
continue;
}
else //you want to stay in "for"
{
<code...>
}
}
}
It seems your problem can be solved by simple nested loops like these :
while(!success){
for (int att = 1; att < 11; att++){
<body>;
if(answer is correct){
success = true;
break;
}
//break will completely finish running the program
}
}
Related
How would I go about running a while loop in C to say N number of times?
For example, I reach this function and then I want to run the while() block 5 times.
// while there are customers
while (customers_length)
{
// check if there are customers waiting
if (index == initial_customers_length)
customers_are_waiting = 0;
// increment one hour
sum++;
// for every cashier subtract one hour
for (i = 0; i < n; i++)
{
cashiers[i].how_many_hours--;
// if cashier has no customers and no customers waiting reset to 0;
if (cashiers[i].how_many_hours < 0)
cashiers[i].how_many_hours = 0;
}
// if a cashier is free and there are no customers waiting, allocate next customer
for (i = 0; i < n; i++)
{
if (!cashiers[i].how_many_hours && customers_are_waiting)
{
cashiers[i].how_many_hours = customers[index];
customers_length--;
// queue next customer in line
index++;
}
if (!cashiers[i].how_many_hours)
customers_length--;
}
}
What's the command for that in gdb?
I want to run the while() block 5 times.
Set a break point on the first if statement inside the loop. Then use ignore $bpnum 5 and continue.
GDB will stop on the if statement breakpoint on 6th iteration through the loop.
I have problems with the break instruction;
Indeed, in my case I reproduce below an example of my calculation code, I work with two nested for loops and if loops.
I would like when the open_bound variable = 0, to completely exit the loops and thus display the value of time t. After execution I see the display of time t = 0 instead of 3 and I have trouble understanding why. Can you please enlighten me?
Is there another alternative to break? (I can't use goto, moreover I parallelize this part in the real code)
Thank you in advance
#include <iostream>
#include <vector>
using namespace std;
int main () {
int numtracers = 1000;
int save_t;
double t;
int open_bound = 0;
int tau = 5;
double int_step = 0.25;
for (int i = 0; i < numtracers; i++) {
// Variable to overwrite the successive positions of each particle
vector <double> coord(2);
coord[0] = 0.1;
coord[1] = 0.2;
int result_checkin;
for(t=0; t<tau-1; t+=int_step) {
save_t = t;
// Function to check if coordinates are inside the domain well defined
// result_checkin = check_out(coord);
if (t == tau-2) result_checkin = 1;
if (result_checkin == 1) { // Particle goes outside domain
if (open_bound == 0) {
break;
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
}
cout << save_t << endl;
return 0;
}
OK, let's first recap on what the break statement does (not counting its use in a switch block): it 'breaks' out of the innermost enclosing for, while or do ... while loop. Thus, if statements aren't considered here - and they aren't really loops, are they.
So, in your main code, you only really have two loops. Your own break will exit the innermost, jumping immediately to the point I've highlighted in the code below. Adding the extra if ... break; code, as I have done, will exit the outer loop:
for (int i = 0; i < numtracers; i++) {
int open_bound = 0; // MUST HAVE HERE to parallelize this loop!
// Variable to overwrite the successive positions of each particle
vector <double> coord(2);
coord[0] = 0.1;
coord[1] = 0.2;
int result_checkin;
for(t=0; t<tau-1; t+=int_step) {
save_t = t;
// Function to check if coordinates are inside the domain well defined
// result_checkin = check_out(coord);
if (t == tau-2) result_checkin = 1;
if (result_checkin == 1) { // Particle goes outside domain
if (open_bound == 0) {
break; // Exits the inner for loop and goes to the "-->HERE" line!
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
else {
coord[0]+=0.1;
coord[1]+=0.1;
}
}
// Your "break" exits the for loop and execution continues -->HERE
if (open_bound == 0) break; // This will (always) exit the outer loop!
}
Does this help? Feel free to ask for further explanation!
EDIT - Note on Loop Parallelisation: If you want to parallelize the
outer loop, then you will only be able to do so if you move the declaration/definition of open_bound inside that outer loop (as I
have done in the code above)! You can't parallelize if your are trying
to modify and test a scalar variable declared outside the loop's
scope.
An alternative to exit all loops you want is to use a bool flag in order to decide when to force the loops to terminate. When you hit open_bound=0 you can first set the flag to false and then break.
Check the following to have an idea about what I mean:
bool go = true;
for (int i = 0; go && CONDITION1; i++)
for (int j = 0; go && CONDITION2; j++)
for (int k = 0; go && CONDITION3; k++)
....
if(open_bound==0){
go = false;
break;
}
A working version off your code is here
What is the difference between the following two for-loops?
for(int i = 0; i < 5; i++)
{
}
and
for(int i = 0; i < 5;)
{
//End of whatever code to do.
i++;
}
According to http://www.cplusplus.com/doc/tutorial/control/, there shouldn't be a difference. Yet when I run my code (the one below), depending on where the iter++ is, there is a difference.
In this program, I have a separate thread running to get an input. What happens when I move the iter++ to the bottom is that when a separate client connects to the server, I have to enter something into the cin stream before it responds.
When iter++ is at the top inside the for loop, this problem does not happen.
The reason why I want my iter++ to be at the bottom is so that when I receive a disconnect, I can delete the session in my map.
for (iter = network->sessions.begin(); iter != network->sessions.end(); iter++)
{
//bool Deleted = false;
int data_length = network->receiveData(iter->first, network_data);
if (data_length < 0)
{
//no data recieved
continue;
}
if (data_length == 0)
{
printf("Data closed GRACEFULLY LOL \n");
continue;
}
int i = 0;
while (i < (unsigned int)data_length)
{
packet.deserialize(&(network_data[i]));
i += sizeof(Packet);
switch (packet.packet_type) {
case INIT_CONNECTION:
printf("server received init packet from client\n");
char Buffer[100];
//Buffer to hold char values of client id
_itoa_s(client_id - 1, Buffer, 10);
sendActionPackets(client_id - 1, Buffer);
break;
case ACTION_EVENT:
printf("server received action event packet from client\n");
break;
case TALK:
ProcessTalkLine(packet.Message, sizeof(packet.Message), iter->first);
//sendTalkPackets(packet.Message,sizeof(packet.Message), iter->first);
break;
case DISCONNECTING:
printf("I HAVE RECEIVED DC CONNECT /n");
char theMessage[MAX_MESSAGE_SIZE];
sprintf_s(theMessage, "%s has disconnected.", Usernames.find(iter->first)->second.c_str());
Usernames.erase(iter->first);
//network->sessions.erase(iter++);
break;
default:
printf("error in packet types\n");
break;
}
}
}
EDIT: Thanks to #Matt McNabb for pointing out that the continue would...well continue. I've put in my iter++ there as well, but the problem that it would not receive the messages until I put in something remains. If I left the iter++ inside the for loop, this problem isn't there.
When you continue it execute the third statement in the for . In your first case this increments i and in the second case it doesn't.
The loops are only the same if you do not use continue (or goto).
These two are not same:
for(int i = 0; i < 5; i++)
{
if (some_condition)
continue;
}
and
for(int i = 0; i < 5;)
{
if (some_condition)
continue;
//End of whatever code to do.
i++;
}
for(int i = 0; i < 5; i++)
{
if (condition)
continue;
//Your Code
}
In above for loop, on condition is true then loop will continue without traversing the line below. But the i value will be definitely incremented.
for(int i = 0; i < 5;)
{
if (condition)
continue;
//Your Code
i++;
}
In second for loop behave same way as previous except on continue the value of i will not be incremented.
In you case if you want surely to put itr++ at the bottom then write like following,
for(int i = 0; i < 5;)
{
if (condition)
goto incrementPoint; //Use goto instead of continue.
//Your Code
incrementPoint: i++;
}
to really see the difference consider the code a compiler will generally generate for a for loop: for(i= initial_value; i<max value; i=i+increment)
NOTE: this is pseudocode and ignores all compiler optimizations
**stat_for_loop**:
execute instructions
i=i+increment
if i<max_value
goto **stat_for_loop**
when you add a continue statements inside the for loop the generally look like this:
**stat_for_loop**:
execute instructions
if(cond)
goto **next_iteration**
execute instructions
**next_iteration**:
i=i+increment
if i<max_value
goto **stat_for_loop**
You can clearly see that if you ignore the iterator incrementation in the for loop and you decide to increment it manually in the for block (like you would do for a while loop), depending on when you add a continue statement, the generated code will be different, hence the execution path will be different
I have a code here,
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
//checking some conditions here for true or false
if(false)
{
break out of this for loop;
}
else if(true)
{
printf("true");
}
}
}
i want to break out of inner for loop and continue with the outer loop . I tried to use break but the control moved out of the parent for loop also.
Any solution for this?
I tried to use break but the control moved out of the parent for loop also.
You must be confused. break only breaks out of the innermost loop/switch, so it can't have stopped the outer loop too (unless by chance the outer loop was on its last iteration, which gave you this false impression).
When you are in doubt like this, you can either step through your code using a debugger, or at the very least insert "tracing" output in your code so that you can verify what it actually does:
for(int i=0;i<5;i++)
{
printf("outer loop %d\n", i);
for(int j=0;j<5;j++)
{
printf("inner loop %d\n", j);
//checking some conditions here for true or false
if(false)
{
printf("breaking out of inner loop\n");
break;
}
else if(true)
{
printf("true in inner loop\n");
}
}
printf("finishing the outer loop %d\n", i);
}
Yes your code is correct and it must work as you have expected.
Unless you have compiled this one and execute something another. :-)
6.8.6.3 The break statement
Constraints
1 A break statement shall appear only in or as a switch body or loop body.
Semantics
2 A break statement terminates execution of the smallest enclosing switch or iteration
statement.
Quoted from ISO/IEC 9899:TC3
So your break should work, as you don't use any pre alpha compiler.
but the problem is more
if (false) //will never be executed, as false is ever fals
{
//code gets never invoked
}
so you don't break out as you never invoke the break;
If you use break in the inner loop then it will definitely move the control to the outer loop.
I think what you might be missing is to reset your false condition after coming out of the inner loop.
It's all based on logic on when you want to break out from the inner loops. Consider the following steps.
Do
For Int x = 1 To 10
Do
Break, Break, Break
Loop
Next x
Loop
Try reconsidering your program logic and implement the break statements using flags.
If you want, you could just overcome by breaking from the inner loops by using the goto statements.
int num[5][5][5];
for (int x = 0; x < 5; x++)
{
for (int y = 0; y < 5; y++)
{
for (int z = 0; z < 5; z++)
{
if (num[x][y][z] == 256)
{
cout << "Number has been found at location: " << x << y << z;
//break the three for loops here, it's unnecessary to check any other locations
goto finish;
}
}
}
}
finish:
Break only breaks the loop in which it is used
and btw if that condition is false it will never execute
Try using a flag and checking it in your for loop conditional.
int stop = 0;
for (int i = 0; !stop && i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
if (false) {
stop = 1;
break;
}
// Condition when true does not need 'else' if breaking.
}
}
for (int i = 0; i<10; i++)
{
//do some validation for record length
//if it is not valid
continue; // goes to the next iteration in for loop for 'i'
for (int j = 0; j<5; j+=2)
{
//do some more validation for individual record
//if it is not valid
Here it should go to the next i if i use continue. Here it will go to the next j
Can anyone please let me know how to do this?
You need to specifically test for a flag in the outer loop if there is something after the inner loop:
for(some_outer_vars){
bool should_skip = false;
// ...
for(some_inner_vars){
// ...
if(your_condition){
should_skip = true;
break;
}
}
if(should_skip)
continue;
// ...
}
Using break; inside the j loop will exit the j loop completely.
But at least spend a couple minutes deciding if an alternate algorithm, approach, or termination condition could remove the need to break in the middle of a loop.
Do you have anything after the inner loop? If not, you can just use break:
for (i = 0; i < 10; i++)
{
if (i is no good)
continue;
for (j = 0; j < 5; j++)
{
if (j is no good)
break;
}
}
If you do need to do something later, you can use break in combination with some other flag.
Place break; instead. This should get you out of the inner loop.
for (int i = o; i<10; i++)
{
}
for (int j = 0; j<5; j+=2)
{
break;
}
"break;" will end your current j loop and go to the next i.
If you can't arrange the logic so that break in the inner loop gets straight to continuing the outer loop, then do this:
for (int i = 0; i<10; i++)
{
if (!valid(i)) continue;
for (int j = 0; j<5; j+=2)
{
if (!valid(i,j)) goto continue_i;
do_whatever_with_i_and_j()
}
more_stuff_here();
continue_i:
}
There, I've said it. The code is shorter, simpler, easier to read and easier to analyse than the version that sets a flag, then breaks, then immediately checks the flag again and conditionally continues.
Another option is this
void inner_loop(int i) {
if (!valid(i)) return;
for (int j = 0; j<5; j+=2)
{
if (!valid(i,j)) return;
do_whatever_with_i_and_j()
}
more_stuff_here();
}
for (int i = 0; i<10; i++)
{
inner_loop(i);
}
Depending what the inner loop does, though, you might find yourself building quite a mechanism to give it access to whatever it's supposed to modify.
Community wiki, because this (or situations like it) has been argued so many times on SO as to practically define "subjective and argumentative".
I try to avoid break and continue when dealing with loops because they are easy to miss and their meanings change if you have to restructure the code later. You can use j=5; when you need to exit the inner loop. If you add a third loop or a switch the meaning of that line doesn't change. Sometimes you will need to add if statements inside your loops testing i and j or even a new variable like bool iIsInvalid but I think that makes the control flow easier to read.