Get rid of goto statement from embedded C/C++ logic - c++

I want to get rid of this goto statement. Can any one tell me the logic for the same. The code below is not the exact code that I want to modify, but it will support my question. Please don't ask the significance of the code when commenting on this post as it is just an example.
int result[i][j];
for (int i = 0; i<100; i++)
{
for (j = 0; j<100; j++)
{
result[i][j] = j++;
if (j == 80)
goto break1;
}
}
break1:
…;

Put those loops in a function, give it a proper name and return; when it is done. If it is complicated enough to need two loops, it deserves a name.
A finished flag is so hard to read that you should put that construct in its own function anyway, making it obsolete.
Exceptions are only for errors you cannot handle locally. Use them to notify higher level functions that something you cannot fix went wrong, not if something that was supposed to happen happened.

I would see three possible solutions.
Put the code into a function and leave that function with return
Use a "finished" flag like already demonstrated well in the answers by Michel Keijzers, Bas in het Feld and EvilTeach.
(C++ only) surround the code-section with a try-catch-block and throw and exception when you want to leave the code. But keep in mind that exceptions are usually supposed to be used for error-handling. So you should only use this pattern when terminating the loops is the result of an error conditions.

Since you want to break two loops, you have to notify the outer loop. You can do this by having a boolean that checks for that:
bool break_loop = false;
for (int i = 0; i < 100; ++i) {
for (int j = 0; j < 100; ++j) {
if (j == 80) {
break_loop = true;
break;
}
}
if (break_loop) break;
}

Use a boolean to break from the for loop(s).
int result[i][j];
bool cont = 1;
for (int i =0;i<100;i++)
{
for(j = 0;j<100;j++)
{
result[i][j] = j++;
if(j == 80)
{
cont = 0;
break;
}
}
if (cont == 0)
break;
}
break1;
(note: not tested on real compiler).

int result[i][j];
for (int i = 0; i<100; i++)
{
for (j = 0; j<100; j++)
{
result[i][j] = j++;
if (j == 80)
{
i = 100;
break;
}
}
}

I sometimes like changing the control variable(s)
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
/* work */
if (j == 80) i = j = 100; // 100 makes both loops terminate
}
}

int result[i][j];
for (int i = 0; i<100; i++)
{
int j;
for (j = 0; j<100; j++)
{
result[i][j] = j++;
if (j == 80)break;
}
if(j == 80) break;
}
Know this is an old question but can be modified simply

Related

C++: How to make break/continue in nested loops

How to beautifully implement the following code?
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < l; k++) {
if (condition1) {
// continue at for k ...
}
if (condition2) {
// continue at for j ...
}
if (condition3) {
// continue at for i ...
}
}
}
}
Usually I'll go with three boolean flag, and after each iteration will check it whether I should break/continue. Is there better way to do that? I was taught never to use goto/labels but looks like it might be useful here?

How can I circle back to the a starting point using a for loop?

I have a std::vector<std::unique_ptr<object>> myObjects_ptrs. I need to, starting in one of my objects, circle back again to where I started.
I am doing this as follows:
while(true)
{
for(int i = 0; i < myObjects_ptrs.size(); ++i)
{
myObjects_ptr[i]->doSomething();
//and here I need to circle back
for(int j = i + 1; j < myObjects_ptr.size(); ++j)
{
//do some things with each other object
}
for(int j = 0; j < i; ++j)
{
//do the same things with the rest of the objects
}
}
}
Is this the standard way of doing that? My problem is that once I detect something, then I dont need to keep going around. For example if I find something during the first loop then there is no need to go through the second loop. I con solve this by adding an extra if before the second loop; but is there a better way?
You could use a modulus, i.e. the two inner loops would become:
int numObjects = myObjects_ptr.size();
for (int j = i + 1; j < numObjects + i + 1; ++j)
{
// Get object
auto& obj = myObjects_ptr[j % numObjects];
}
You could replace the two inner loops with something like this:
for(int j = i + 1;; j++)
{
j %= myObjects_ptr.size();
if (j == i)
{
break;
}
// Do stuff
}

Stack Smashing Error While Working with CStrings

I am working on a small project and I am absolutely stuck. The purpose of the function I'm working on is to rearrange and change a Cstring based on a few preset rules. Where my issue lies is within the second portion of my swapping algorithm I came up with.
for(int i = 0; i < len; i++)
{
if(sentence[i] == SPACE)
{
space++;
spacePlace[counter] = i;
counter++;
}
}
for(int i = 0; i < space; i++)
{
if(i == 0)
{
count2 = 0;
for(int h = 0; h < 20; h++)
{
temp1[h] = NUL;
temp2[h] = NUL;
}
for(int j = 0; j < spacePlace[0]; j++)
temp1[j] = sentence[j];
for(int m = spacePlace[0]; m < spacePlace[1]; m++)
{
temp2[count2] = sentence[m];
count2++;
}
.
.
.
the first for loops executes perfectly and the output is great, but the second for loop always messes up and ends up sending me a stack smashing error. For more reference, sentence is a cstring passed to the function, and temp1 and temp2 are also cstrings. Any help or points in the right direction would be a godsend. Thanks!

How can I not allow an element in an array to not increment if it was already incremented on that run in the loop?

I am trying to get the summary of CFG with given input. I have to list the terminals with the count of how many times it appears in the rule. However, I'm having trouble with it counting multiple terminals on the same rule.
for (int i = 0; i < cfg.size(); i++)
{
for (int j = 0; j < cfg[i].size(); j++)
{
for (int k = 0; k < terminal.size(); k++)
{
if (strcmp(cfg[i][j].c_str(), terminal[k].c_str()) == 0)
{
//TO-DO if counter[k] already incremented do not increment counter[k] again
counter[k]++;
break;
}
}
}
}
For example if the rule is
Z -> a b b b
It will return 3 for b when the correct answer would be 1.
Any help on how I can how I can leave that rule after it has already been counted would be great. Thank you
I'm not sure if I understand what you mean, but maybe changing the loops order would help?
for (int i = 0; i < cfg.size(); ++i)
{
for (int k = 0; k < terminal.size(); ++k)
{
for (int j = 0; j < cfg[i].size(); ++j)
{
if (strcmp(cfg[i][j].c_str(), terminal[k].c_str()) == 0)
{
++counter[k];
break;
}
}
}
}

Issue with array (if (zeds[i].x == zeds[i].x))

I've created a simple game in C++ in which a player must avoid being bitten by zombies to survive.
The zombies are stored as Z characters in an array called zeds.
I am trying to write a function that can check if any zombies collide, and act accordingly.
I've written this if statement:
for (int i; i < MAXZEDS; ++i);
if (zeds[i].x == zeds[i].x && zeds[i].y == zeds[i].y)
{
--zlives;
updateLives();
}
Obviously it doesn't work, I'm just wondering if I can somehow rewrite this to only decrement zlives if a zombie collides with another zombie but NOT itself.
Apologies for the title I couldn't find a better way to summarize my issue. Thanks in advance for any help.
You need a double loop so you can compare two different zombies.
Something like this.
for (int i = 0; i < MAXZEDS - 1; ++i)
{
// Looping from i + 1 ensures that we only test each pair once.
for (int j = i + 1; j < MAXZEDS; ++j)
{
if (zeds[i].x == zeds[j].x && zeds[i].y == zeds[j].y)
{
--zlives;
updateLives();
}
}
}
The simplest way is 2 loops.
for (int i = 0; i < MAXZEDS; ++i) {
for (int j = i+1; j < MAXZEDS; ++j) {
if (zeds[i].x == zeds[j].x && zeds[i].y == zeds[j].y)
{
--zlives;
updateLives();
}
}
}
If the object order in zeds is not important, and operator<() is defined correctly for the element type of zeds, then you could sort zeds and check consecutive elements to get lower complexity.
Try using nested for loops:
for (int i = 0; i < MAXZEDS; i++)
{
for (int j = 0; j < MAXZEDS; j++)
{
if (i == j) continue; // Don't compare the current zed with itself
else if (zeds[i].x == zeds[j].x && zeds[i].y == zeds[j].y)
{
--zlives;
updateLives();
}
}
}
This iterates through zeds twice and compares each item in the array with each other item. I am sure there are more efficient ways, but this is the simplest.