In a C# (feel free to answer for other languages) loop, what's the difference between break and continue as a means to leave the structure of the loop, and go to the next iteration?
Example:
foreach (DataRow row in myTable.Rows)
{
if (someConditionEvalsToTrue)
{
break; //what's the difference between this and continue ?
//continue;
}
}
break will exit the loop completely, continue will just skip the current iteration.
For example:
for (int i = 0; i < 10; i++) {
if (i == 0) {
break;
}
DoSomeThingWith(i);
}
The break will cause the loop to exit on the first iteration - DoSomeThingWith will never be executed. This here:
for (int i = 0; i < 10; i++) {
if(i == 0) {
continue;
}
DoSomeThingWith(i);
}
Will not execute DoSomeThingWith for i = 0, but the loop will continue and DoSomeThingWith will be executed for i = 1 to i = 9.
A really easy way to understand this is to place the word "loop" after each of the keywords. The terms now make sense if they are just read like everyday phrases.
break loop - looping is broken and stops.
continue loop - loop continues to execute with the next iteration.
break causes the program counter to jump out of the scope of the innermost loop
for(i = 0; i < 10; i++)
{
if(i == 2)
break;
}
Works like this
for(i = 0; i < 10; i++)
{
if(i == 2)
goto BREAK;
}
BREAK:;
continue jumps to the end of the loop. In a for loop, continue jumps to the increment expression.
for(i = 0; i < 10; i++)
{
if(i == 2)
continue;
printf("%d", i);
}
Works like this
for(i = 0; i < 10; i++)
{
if(i == 2)
goto CONTINUE;
printf("%d", i);
CONTINUE:;
}
When to use break vs continue?
Break - We're leaving the loop forever and breaking up forever. Good bye.
Continue - means that you're gonna give today a rest and sort it all out tomorrow (i.e. skip the current iteration)!
(Corny stories ¯¯\(ツ)/¯¯ and pics but hopefully helps you remember.
Grip Alert: No idea why those words are being used. If you want to skip the iteration, why not use the word skip instead of continue? This entire Stack overflow question and 1000s of developers would not be confused if the proper name was given.)
break would stop the foreach loop completely, continue would skip to the next DataRow.
There are more than a few people who don't like break and continue. The latest complaint I saw about them was in JavaScript: The Good Parts by Douglas Crockford. But I find that sometimes using one of them really simplifies things, especially if your language doesn't include a do-while or do-until style of loop.
I tend to use break in loops that are searching a list for something. Once found, there's no point in continuing, so you might as well quit.
I use continue when doing something with most elements of a list, but still want to skip over a few.
The break statement also comes in handy when polling for a valid response from somebody or something. Instead of:
Ask a question
While the answer is invalid:
Ask the question
You could eliminate some duplication and use:
While True:
Ask a question
If the answer is valid:
break
The do-until loop that I mentioned before is the more elegant solution for that particular problem:
Do:
Ask a question
Until the answer is valid
No duplication, and no break needed either.
All have given a very good explanation. I am still posting my answer just to give an example if that can help.
// break statement
for (int i = 0; i < 5; i++) {
if (i == 3) {
break; // It will force to come out from the loop
}
lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}
Here is the output:
0[Printed] 1[Printed] 2[Printed]
So 3[Printed] & 4[Printed] will not be displayed as there is break when i == 3
//continue statement
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue; // It will take the control to start point of loop
}
lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}
Here is the output:
0[Printed] 1[Printed] 2[Printed] 4[Printed]
So 3[Printed] will not be displayed as there is continue when i == 3
Break
Break forces a loop to exit immediately.
Continue
This does the opposite of break. Instead of terminating the loop, it immediately loops again, skipping the rest of the code.
Simple answer:
Break exits the loop immediately.
Continue starts processing the next item. (If there are any, by jumping to the evaluating line of the for/while)
By example
foreach(var i in Enumerable.Range(1,3))
{
Console.WriteLine(i);
}
Prints 1, 2, 3 (on separate lines).
Add a break condition at i = 2
foreach(var i in Enumerable.Range(1,3))
{
if (i == 2)
break;
Console.WriteLine(i);
}
Now the loop prints 1 and stops.
Replace the break with a continue.
foreach(var i in Enumerable.Range(1,3))
{
if (i == 2)
continue;
Console.WriteLine(i);
}
Now to loop prints 1 and 3 (skipping 2).
Thus, break stops the loop, whereas continue skips to the next iteration.
Ruby unfortunately is a bit different.
PS: My memory is a bit hazy on this so apologies if I'm wrong
instead of break/continue, it has break/next, which behave the same in terms of loops
Loops (like everything else) are expressions, and "return" the last thing that they did. Most of the time, getting the return value from a loop is pointless, so everyone just does this
a = 5
while a < 10
a + 1
end
You can however do this
a = 5
b = while a < 10
a + 1
end # b is now 10
HOWEVER, a lot of ruby code 'emulates' a loop by using a block.
The canonical example is
10.times do |x|
puts x
end
As it is much more common for people to want to do things with the result of a block, this is where it gets messy.
break/next mean different things in the context of a block.
break will jump out of the code that called the block
next will skip the rest of the code in the block, and 'return' what you specify to the caller of the block. This doesn't make any sense without examples.
def timesten
10.times{ |t| puts yield t }
end
timesten do |x|
x * 2
end
# will print
2
4
6
8 ... and so on
timesten do |x|
break
x * 2
end
# won't print anything. The break jumps out of the timesten function entirely, and the call to `puts` inside it gets skipped
timesten do |x|
break 5
x * 2
end
# This is the same as above. it's "returning" 5, but nobody is catching it. If you did a = timesten... then a would get assigned to 5
timesten do |x|
next 5
x * 2
end
# this would print
5
5
5 ... and so on, because 'next 5' skips the 'x * 2' and 'returns' 5.
So yeah. Ruby is awesome, but it has some awful corner-cases. This is the second worst one I've seen in my years of using it :-)
Please let me state the obvious: note that adding neither break nor continue, will resume your program; i.e. I trapped for a certain error, then after logging it, I wanted to resume processing, and there were more code tasks in between the next row, so I just let it fall through.
To break completely out of a foreach loop, break is used;
To go to the next iteration in the loop, continue is used;
Break is useful if you’re looping through a collection of Objects (like Rows in a Datatable) and you are searching for a particular match, when you find that match, there’s no need to continue through the remaining rows, so you want to break out.
Continue is useful when you have accomplished what you need to in side a loop iteration. You’ll normally have continue after an if.
if you don't want to use break you just increase value of I in such a way that it make iteration condition false and loop will not execute on next iteration.
for(int i = 0; i < list.Count; i++){
if(i == 5)
i = list.Count; //it will make "i<list.Count" false and loop will exit
}
Since the example written here are pretty simple for understanding the concept I think it's also a good idea to look at the more practical version of the continue statement being used.
For example:
we ask the user to enter 5 unique numbers if the number is already entered we give them an error and we continue our program.
static void Main(string[] args)
{
var numbers = new List<int>();
while (numbers.Count < 5)
{
Console.WriteLine("Enter 5 uniqe numbers:");
var number = Convert.ToInt32(Console.ReadLine());
if (numbers.Contains(number))
{
Console.WriteLine("You have already entered" + number);
continue;
}
numbers.Add(number);
}
numbers.Sort();
foreach(var number in numbers)
{
Console.WriteLine(number);
}
}
lets say the users input were 1,2,2,2,3,4,5.the result printed would be:
1,2,3,4,5
Why? because every time user entered a number that was already on the list, our program ignored it and didn't add what's already on the list to it.
Now if we try the same code but without continue statement and let's say with the same input from the user which was 1,2,2,2,3,4,5.
the output would be :
1,2,2,2,3,4
Why? because there was no continue statement to let our program know it should ignore the already entered number.
Now for the Break statement, again I think its the best to show by example. For example:
Here we want our program to continuously ask the user to enter a number. We want the loop to terminate when the user types “ok" and at the end Calculate the sum of all the previously entered numbers and display it on the console.
This is how the break statement is used in this example:
{
var sum = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var input = Console.ReadLine();
if (input.ToLower() == "ok")
break;
sum += Convert.ToInt32(input);
}
Console.WriteLine("Sum of all numbers is: " + sum);
}
The program will ask the user to enter a number till the user types "OK" and only after that, the result would be shown. Why?
because break statement finished or stops the ongoing process when it has reached the condition needed.
if there was no break statement there, the program would keep running and nothing would happen when the user typed "ok".
I recommend copying this code and trying to remove or add these statements and see the changes yourself.
As for other languages:
'VB
For i=0 To 10
If i=5 then Exit For '= break in C#;
'Do Something for i<5
next
For i=0 To 10
If i=5 then Continue For '= continue in C#
'Do Something for i<>5...
Next
Related
I am new to Kattis and trying solve the challenge Jumbo Javelin with C# but I get run time error even though I am exiting my program with 0.
Here is my code:
using System;
namespace JumboJavelin
{
class Program
{
static void Main(string[] args)
{
int l = int.Parse(Console.ReadLine());
int sum = 0;
int loss = 1;
for (int n = 0; n <= 100; n++)
{
sum += l;
if((n + 1) % 2 == 0 && !n.Equals(0))
{
sum -= ((n + 1) / 2)*loss;
}
try
{
l = int.Parse(Console.ReadLine());
}
catch (FormatException)
{
break;
}
}
Console.WriteLine(sum);
Environment.Exit(0);
}
}
}
Can someone please help me? I know my solution eventually outputs the wrong answer but right now I am trying to get rid of the run time error since it works perfectly fine on Visual Studio 2019.
All help is appreciated. Thanks
If you change the error your catch to Exception you will see that it is actually a wrong answer, so something goes wrong. You do exit your program with an exit code 0 at the bottom of your code, however, it throws an Exception somewhere else. Two things to consider:
First, the problem statement explains that as a first input, you get an integer N (this N indicates the amount of steel rods he has) and CAN BE between 1 and 100 (1 not inclusive hence, 1<N<=100). You now have a loop that always loops from 1 to 100. And the loop should loop from 1 up to and including whatever value N is. Try to see what you can do about that.
Second you read the input at the "tail" of the loop. This means that after the last cycle you do another read input. And that you do not read the first l. Try changing reading the input for l at the beginning of the loop. (and the first input you read in your Main, should not be for l (see point 1)).
See how far this gets you, is something is not clear please let me know.
As Kasper pointed out, n is dynamically provided on the first line; don't assume you have 100 lines to collect with for (int n = 0; n <= 100; n++).
There's no need to handle errors with the format; Kattis will always adhere to the format they specify. If something goes wrong parsing their input, there's no point trying to catch it; it's up to you to fix the misunderstanding. It's better to crash instead of catch so that you won't be fooled by Kattis telling you the failure was due to a wrong answer.
A simple approach is as follows:
Collect n from the first line of input; this is the preamble
Loop from 0 to n, collecting each line
Accumulate the values per line into a sum
Print sum - n + 1, the formula you can derive from their samples
using System;
class JumboJavelin
{
static void Main(string[] args)
{
int n = int.Parse(Console.ReadLine());
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += int.Parse(Console.ReadLine());
}
Console.WriteLine(sum - n + 1);
}
}
You can use this pattern on other problems. You won't always aggregate one result after n lines of input though; sometimes the input is a single line or you have to print something per test case. Some problems require you to split and parse each line on a delimiter.
Regardless of the case, focus on gathering input cleanly as a separate step from solving the problem; only combine the two if you're confident you can do it without confusion or if your solution is exceeding the time limit and you're sure it's correct otherwise.
I 'm not sure how to explain this and I cannot find an answer anywhere. I have a for loop that loops through lines that are represented through strings.
for (int i = 0; i < dataLines.Length; i++)
{
jumpPoint:
Debug.Log("Jumped");
string[] words = dataLines[i].Split();
.
.
. "words[] manipulation and reading"
.
.
}
I have no problems with any of my data processing or things that happen in the loop.
But I have an instance where i need to go to a previous dataLine[] and continue from that point (also re-runs code that has already been run since that point).
What I am doing essentially boils down to
i = ?; //arbitrary number for the situation that is definitely not out of bounds for the loop
goto jumpPoint;
Ive also tried without the jump point also just letting the loop cycle to the next after resetting the for loop index.
I know it's not an issue with the jump point as its used for unrelated things and the jump works fine. Also worth mentioning, that in those instances, I am increasing the i index so the for loop prematurely advances and that works perfect.
So why can I not go backwards in the loop? Is that just something that is not possible?
Not sure if I understand but you mean something like this:
var i = 0;
var startRun = true;
while (true)
{
if (!startRun && i == dataLines.Length - 1)
return;
if (startRun)
startRun = false;
/* do stuff */
if (needToJump)
{
clearLogicOrWhatever();
i = whereYouNeedToJump;
}
else
i++;
}
Of course you will need more validation if going out of index, if step exists or in range and other stuff, this is just like a proof of concept / pseudo.
Nothing is stopping you from going backwards in the loop. You are in control of your code logic, so all you have to do is when your "jumpPoint" condition is met, just change the iterator i back to the previous value that you desire.
For example: Let's say I want to jump back and re-run something because it had the word "jump" in it.
Console.WriteLine("App started.");
List<string> dataLines = new List<string>() { "this is a phrase", "This is another but with jump in it", "this is the last" };
bool alreadyJumped = false;
for (int i = 0; i < dataLines.Count; i++)
{
Console.WriteLine($"Currently Iterating: {i}");
string[] words = dataLines[i].Split();
Console.WriteLine($"Do some with this data: {dataLines[i]}");
if (words.Contains("jump") && !alreadyJumped)
{
alreadyJumped = true;
// Reset the i value so that the next iteration will run again.
i = i - 1;
}
else if (alreadyJumped)
{
// Once
alreadyJumped = false;
}
}
Console.WriteLine("App done.");
This will produce this output:
App started.
Currently Iterating: 0
Do some with this data: this is a phrase
Currently Iterating: 1
Do some with this data: This is another but with jump in it
Currently Iterating: 1
Do some with this data: This is another but with jump in it
Currently Iterating: 2
Do some with this data: this is the last
App done.
I am creating for my studies a program a simple one. In this program I need to make a sentence of 10 words. After the last input however I want to make it stop. So what I tried is this:
Create an empty string called textt, use a while loop since I make it always true it will proceed, create a string with the assignement that shows up in the program to the user aSentence its called, take an int named count and give it the value of 0, then I start my for loop I use the for loop cause I can add a condition and iterator so it stops and of course the initializer.
In the for loop I: print out the aSentence ( the user will read this ), I put a string called input and let the user put in a word ( I'm a beginner I do not know if how to make an error if the user put two words but thats not the assignment now ), I put the string textt since they are immutable but not in here and I add " " for create empty space and of course the input. Then I print out the textt what the user wrote down and I increment ( if I say this correctly ) with i++.
Then I start an if statement which says that if i ( see my for loop ) is equal == to 9 cause I increment this in my for loop it should print out End of the sentence, show the whole textt and then break.
However for some reason the loop is infinite everytime you input something. And the line End of the sentence will show up now and then and now when the loop should be finished at 9.
My question how do I fix this to make sure the sentencenends when 10 words have been inputted by the user and the End of the sentence pops up at exactly 10 input words.
using System;
namespace Opgave_10_woorden_invoegen_in_1_string_plakken
{
class Program
{
static void Main(string[] args)
{
//Create a program that stops after input of 10 words
string textt = "";
while (true)
{
string aSentence = new string("We are making a sentence of 10 words.");
int count = 0;
for (int i = 0; i < 9; i++)
{
Console.WriteLine(aSentence);
string input = Console.ReadLine();
textt = textt + " " + input;
Console.WriteLine(textt, i++);
if (i == 9)
{
Console.WriteLine("End of the sentence", textt);
break;
}
}
}
}
}
}
Combining my comments into an answer:
while(true) will run forever (unless some code calls break). Your inner for loop should work fine - why not just remove the while loop?
And your for loop condition should be < 10, since you want 10 items and the count is starting at 0. And you don't need a break statement inside a for loop, since the condition is built-in at the for statement.
There's also a problem in that you're incrementing i twice: once in the for statement iterator and again in the body of the for loop, so i will become 9 in only 5 iterations. Remove the inner increment. See the for statement documentation here.
Also, you don't need to do call a string constructor for the string assignment (does that even compile?). Just assign the string directly: string aSentance = "We are making a sentence of 10 words.";
Finally, you might look at the documentation for Console.WriteLine. The second variable you're passing to it isn't likely what you think it should be.
To put this all into a sample:
static void Main()
{
//Create a program that stops after input of 10 words
string textt = "";
string aSentence = "We are making a sentence of 10 words.";
for (int i = 0; i < 10; i++)
{
Console.WriteLine(aSentence);
textt = textt + " " + Console.ReadLine();
Console.WriteLine(textt);
}
Console.WriteLine("End of the sentence");
Console.ReadKey();
}
You while (true) statement means that your loop runs forever.
You are trying to break out of this by using break. But as this is executed inside an inner for loop, then it will only break out of that inner loop and not your outer while loop, which is what you intend and expect.
You have no need for the outer while loop, so simply removing it will solve the problem.
If you want 10 inputs then you also need to change your for loop to run for 10 iterations, not 9 as your currently have.
Also, you should use StringBuilder class when concatenating strings together so many times, as it is more efficient.
See: https://www.dotnetperls.com/stringbuilder for more details
I'm aware (from similar posts) that infinite while loops are notorious for causing Unity3d to crash. I'm tring to impliment a while loop within something I'm working on, which I'm fairly sure isn't 'infinite', yet causes the game to crash.
The idea of the logic is to check a list of integers for consecutive numbers and use that as the basis to apply a bonus. The list contains 'effective shots', and has a new int added every time a shot is fired - the more consecutive effective shots, the higher the bonus.
Here's what I have:
int count = 0;
int firstItem = 0;
int multiples = 3;
int currentMultiple = 0;
int bonusX = 0;
foreach (int i in effectiveShots)
{
if (count == 0)
{
firstItem = i;
count = 1;
}
else if (i == firstItem + count)
{
count++;
}
}
while (count >= multiples)
{
currentMultiple = multiples;
if (count == currentMultiple + multiples)
{
bonusX += 1;
}
if (bonusX > 10 || gameOver)
break;
UnityEngine.Debug.Log(bonusX);
}
The logic to check for consective entries in the effectiveShots list was taken from #Jon Skeet's answer here. Though this appears to work, I think that this may be the issue. As soon as a shot is missed, count needs to be reset. Any ideas or suggestions?
The while loop should then be entered once the count of consecutive effective shots has reached the first multiple, i.e. 3 shots. Then, for every set of consequtive effective shots thereafter, increment the bonus, for example:
3 shots: bonusX = 1
6 shots: bonusX = 2
9 shots: bonusX = 3
12 shots: bonusX = 4
and repeat this until `count` is no longer >= 3, i.e. the player missed a shot.
The issue is that as soon as I hit 3 consequtive shots and enter this loop, the game crashes. I dont think I would call this an infinite loop, since missing a shot - setting count == 0 - would mean the while conditions are no longer true, so drop out of the loop (I think?). I also added an additional check to break out of the loop under certain circumstances, but this doesnt make a difference.
If you are able to give a steer as to how to fix this crashing, or have a suggestion on a better approach in general, it would be appreciated!
Nothing in your while loop changes the value of either count or multiples and so the condition will always evaluate to the same value => Infinite loop
I need to find a way for to stop a cycle/loop if correct text is introduced, as if multiple tasks were running.
Anybody who can help me?
If you're in a loop you can 'stop the cycle' with break;.
for (int i = 0; i < someLength; i++) {
if (someText == someotherText) {
break;
}
}
This will only break out of the current loop - that is, it "terminates the closest enclosing loop" - mind you, so if you're in a nested loop it will 'fall' into the next and continue that cycle.