How to make "for" with stop? - c#

This is my code:
switch(gift1)
{
case 1:
for (int ik = 0; allbuild[ik] == g[1]; ik++)
{
if (allbuild[ik] == 0)
allbuild[ik] = g[1];
}
break;
case 2:
for (int ik = 0; allbuild[ik] == g[2]; ik++)
{
if (allbuild[ik] == 0)
allbuild[ik] = g[2];
}
break;
}
I want this:
if allbuild[ik] == 0, then it gets value from g[1] or g[2] and "for" ends, but it's doesnt works like I want. allbuild gets value for all items.
allbuild[1] = g[1];
allbuild[2] = g[2];
allbuild[3] = g[3];
and so on, to albuild[100].

Use break;, which jumps to the end of innermost for loop.
For example:
for (int ik = 0; allbuild[ik] == g[1]; ik++)
{
if (allbuild[ik] == 0)
{
... do what it is that you want to do ...
break;
}
}

First, I doubt whether for loop conditions i.e. allbuild[ik] == g[2] and alike are valid; probably you want to test (potentially) all the items.
Next the copy-pasted switch with 100 brunches looks really ugly, let's cram it into the loop:
//TODO: check loop condition
for (int ik = 0; allbuild[ik] == g[gift1]; ik++)
if (allbuild[ik] == 0) {
allbuild[ik] = g[gift1];
break; // <- break the "for loop"
}

It's unclear what you're asking. for loops run on conditions specified in the initial part:
"int ik = 0; allbuild[ik] == g[1]; ik++"
where
allbuild[ik] == g[1]
is the condition it is evaluating. If that no longer holds true, then it will stop iterating. You can do a lot of things to make this evaluate to false.
However, you can also escape your for loop using a lot of other mechanism:
use the break statement to stop the for loop entirely, and continue on the next statement.
use a continue statement to skip the rest of the current iteration of the loop
use a return statement to get out of the current method
use a goto statement (highly unrecommended)
throw an Exception
use an exit code eg. Environment.Exit(code) statement
I suggest you read up on for loops and debug your code line by line. This is applicable in all languages.

The reason you don't get what you're expecting is that at the end of the block ik gets incremented so that exit condition is comparing the next value in allbuild[] with g[1].
Correct usage of break would be:
switch(gift1)
{
case 1:
{
for (int ik = 0; allbuild[ik] == g[1]; ik++)
{
if (allbuild[ik] == 0)
{
allbuild[ik] = g[1];
break;
}
}
break;
}
case 2:
{
for (int ik = 0; allbuild[ik] == g[2]; ik++)
{
if (allbuild[ik] == 0)
{
allbuild[ik] = g[2];
break;
}
}
break;
}
}
Actually it looks like you are looking for this code:
if (/*condition you need is unclear, according to your code it is: allbuild[0] != g[gift1]*/)
{
for (int ik = 0; ik < allbuild.Length; ik++)
{
if (allbuild[ik] == 0)
{
allbuild[ik] = g[gift1];
break;
}
}
}

Related

Exception Handling, C#

I came across this situation however I don't know how do I handle this exception when the user enters a number outside of the index of the string or any other datatype. In that condition I want the program to display the exception and go back to the first if statement. The code must be as basic as possible as I have just started learning programming. I know the use of 'Try Catch' (or so I think) but I can't determine how to use it here.
choice = int.Parse(Console.ReadLine());
if (arr[choice] != 'X' && arr[choice] != 'O')
{
if (player % 2 == 0)
{
arr[choice] = 'O';
player++;
}
else
{
arr[choice] = 'X';
player++;
}
}
else
{
Console.WriteLine("Sorry the row {0} is already marked with {1}", choice,arr[choice]);
Console.WriteLine("\n");
}
You can do it like this:
int choice;
bool isValidChoice = int.TryParse(Console.ReadLine(), out choice) && choice >= 0 && choice < arr.Length;
if (isValidChoice && arr[choice] != 'X' && arr[choice] != 'O') {
if (player % 2 == 0) {
arr[choice] = 'O';
player++;
} else {
arr[choice] = 'X';
player++;
}
} else if (!isValidChoice) {
Console.WriteLine("Sorry you have not entered a valid in-range integer");
} else {
Console.WriteLine("Sorry the row {0} is already marked with {1}", choice, arr[choice]);
Console.WriteLine("\n");
}
Some explanations:
int.TryParse, is effectively the equivalent of
int choice;
bool isValid = false;
try {
choice = int.Parse(Console.ReadLine());
isValid = true;
} catch {}
&& will only be evaluated only when the previous statement is correct. So in
choice >= 0 && choice < arr.Length the choice < arr.Length will only be checked if the choice >= 0 is correct
If you want to retry as long as the input is invalid. Try using the while(!isValidChoice) loop. I will not tell you how, as I think it will be a good learning experience.

switch while won't loop

This is part of a program I'm writting. My main porblem is that once it goes trough one of the cases, tit won't loop so it's useless as it is. Any help? (Sorry for the variables in Spanish, also a couple of functions i created appear in the cose which are in the program and work just fine so I don't thin they have anything to do with the problem).
static void Main(string[] args)
{
int minutos_restantes = 480;
int opcion;
int valorComercial = 0;
Tarea[] listado_tareas = new Tarea[10];
CrearTareas(ref listado_tareas);
Console.WriteLine("1. Mostrar tareas. \n2. Asignar tarea \n3. Salir, \n Elige opción: ");
opcion = Convert.ToInt32(Console.ReadLine());
switch (opcion)
{
case 1:
Imprimirtareas(listado_tareas);
break;
case 2:
Console.WriteLine("Seleccionar número de tarea: ");
int n = Convert.ToInt32(Console.ReadLine())-1;
if (n < 0 || n > 10)
{
Console.WriteLine("TAREA INEXISTENTE");
}
else if (listado_tareas[n].realizada == true)
{
Console.WriteLine("TAREA YA REALIZADA");
}
else if((minutos_restantes - listado_tareas[n].tiempo) <= 0)
{
Console.WriteLine("TIEMPO INSUFICIENTE");
}
else
{
listado_tareas[n].realizada = true;
minutos_restantes -= listado_tareas[n].tiempo;
}
break;
} while (opcion != 3) ;
}
I don't think you can loop over a switch like this.
Try doing the while separate:
do
{
switch (opcion)
{
case 1:
Imprimirtareas(listado_tareas);
break;
case 2:
Console.WriteLine("Seleccionar número de tarea: ");
int n = Convert.ToInt32(Console.ReadLine())-1;
if (n < 0 || n > 10)
{
Console.WriteLine("TAREA INEXISTENTE");
}
else if (listado_tareas[n].realizada == true)
{
Console.WriteLine("TAREA YA REALIZADA");
}
else if((minutos_restantes - listado_tareas[n].tiempo) <= 0)
{
Console.WriteLine("TIEMPO INSUFICIENTE");
}
else
{
listado_tareas[n].realizada = true;
minutos_restantes -= listado_tareas[n].tiempo;
}
break;
}
}while (opcion != 3) ;
There's no such construct:
switch
{
} while (...);
In C#. What you've actually written is:
switch
{
}
while (...);
Which is another way of writing
switch
{
}
while (...)
{
}
I suspect you want to put your switch statement inside a while or a do...while loop.
Go for something like this:
int opcion = 0;
do
{
opcion = Convert.ToInt32(Console.ReadLine());
switch (opcion)
{
...
}
} while (opcion != 3);
Check this one too: While Loop in C# with Switch Statement
This is broken code.
You have a switch() {} statement (without default and those breaks cause you to fall out of its scope) and a while (condition) /*do nothing*/; statement.
The intention is do{switch(){}}while() ?
Time to do some reading...
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/while
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/do
You should do :-
while (condition)
{
switch
{
}
}

Break for loop statement with nested switch

I'm trying to break a forloop using break as traditional, but in this case I find myself stuck with this nested switch where the break only works into the switch scope and the loop keeps iterating.
for (int i = 0; i < lenght; i++)
{
switch (enum)
{
case Enum.some_1: break;
case Enum.some_2: break;
case Enum.some_3: break;
}
}
There are multiple options to approach this:
Using helper variable
bool exit = false;
for (int i = 0; i < length && !exit; i++)
{
switch(enum)
{
case Enum.case_which_breaks:
exit = true;
break;
// other cases
}
// some other code, which may use `i`
}
Using helper method
This would be simpler, if you could refactor out the whole for block into a helper method. In this case, you'll use return rather than break.
private Result HandleInternally(int length, Enum enum, Request params)
{
for (int i = 0; i < length; i++)
switch (enum)
{
case Enum.case_which_breaks:
Result result = new Result(); //populate the result
return result;
// other cases
}
}
And then in the consuming code simply call the method.
bool exitForLoop = false;
for (int i = 0; i < length && !exitForLoop; i++)
{
switch (enum)
{
case Enum.some_1: exitForLoop = true; break;
case Enum.some_2: break;
case Enum.some_3: break;
}
}
bool exit = false;
int i = 0;
while (!exit && i < length)
{
switch (enum)
{
case Enum.some_1: exit = true; break;
case Enum.some_2: exit = true; break;
case Enum.some_3: exit = true; break;
}
i++;
}

C# console random number guess game

I'm working on a random number guessing game as a c# console program. It's done with the code and working. However, there is a part that I want to make better:
I declared an instance of a Guess class I created, now how to make this part more efficient?
int counter = 0;
do
{
myGuess.UserGuess = GetUserGuess(); //read user guess
if (myGuess.Compair() == "match")
{
Console.WriteLine("\n\t Correct!You WIN !");
}
else if (myGuess.Compair() == "high")
{
if (counter < 3)
Console.WriteLine("\n\tTry a lower number,");
else
Console.WriteLine("\n\tSorry you LOSE !, The right number is " + myGuess.RndNum);
counter++;
}
else if (myGuess.Compair() == "low")
{
if (counter < 3)
Console.WriteLine("\n\tTry a higher number,");
else
Console.WriteLine("\n\tSorry you LOSE !, The right number is " + myGuess.RndNum);
counter++;
}
} while (myGuess.Compair() != "match" && counter < 4);
Thanks in advance.
What does "Compair()" function look like? It seems like that could return an integer rather than a string for a simpler function. An example of that looks like:
// just an example implementation
public int Compair() {
if (UserGuess < actualValue) return -1;
if (UserGuess > actualValue) return 1;
return 0;
}
And then your routine becomes:
int counter = 0;
bool success = false;
do
{
myGuess.UserGuess = GetUserGuess();
int compair= myGuess.Compair()
switch (compair) {
case 0:
Console.WriteLine("\n\t Correct!You WIN !");
success = true;
break;
case 1:
case -1:
if (counter < 3) Console.WriteLine("\n\tTry a {0} number,", compair == -1 ? "lower" : "higher");
break;
}
counter++;
if (counter >= 3 && !success)
Console.WriteLine("\n\tSorry you LOSE !, The right number is " + myGuess.RndNum);
} while (!success && counter < 4);
That should do it! This should be faster because it isn't using string comparisons, it might be a bit easier to read and it should have fixed a few logical issues.
Note - I made a few assumptions about the use of properties so this example might not compile out of the get but it should get you most of the way there. Best of luck!

Break inside switch Cannot Terminate FOR Loop [duplicate]

This question already has answers here:
Break out of a while loop that contains a switch statement
(15 answers)
Closed 9 years ago.
I have a code snippet :
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
break;
break;//This is unreachable and so i cannot Terminate the For Loop within the SWITCH
}
}
As described in a comment I cannot terminate the For Loop directly from the Switch, only if I declare a boolean and at the End of Switch test
if(LoopShouldTerminate)
break;
PS : or maybe I'm very confused!
[POST]
I got the message ,and the problem is Solved ,but i would like to asume that using Switch within a for loop isn't a god idea ,because i heard from lot of developer's i should break from loop in the moment when i get the desired result ,so using switch need's extra boolean or push the Int i value to 50 direclty , but what would happen if we're using while loop ?
Solution 1: Move the loop and the switch to different methods:
for(int i = 0; i < 50; ++i)
{
if (DoCheckStatus(i)) break;
}
...
bool DoCheckStatus(int i)
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
}
Solution 2: Adapt the above to eliminate the loop with an eager extension method:
static void DoWhile<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
foreach(T item in sequence)
if (!predicate(item)) return;
}
...
Enumerable.Range(0, 50).DoWhile(DoCheckStatus)
Solution 3: Adapt the above to eliminate the loop and the helper method:
Enumerable.Range(0, 50).DoWhile(i=>
{
switch(CheckStatus(i))
{
case 1 : return true;
default: return false;
}
});
You can use goto in order to break out of the loop within the switch.
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
goto outofloop;
}
}
:outofloop
// more code
One of the few good uses of goto...
Just change the value of i:
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
i += 50;
break;
}
}
If there is no other code after the switch you can just check in the for loop itself whether to continue looping:
bool doContinue = true;
for (int i = 0; i < 50 && doContinue; i++)
{
n = checkStatus();
switch (n)
{
case 1:
doContinue = false;
}
}
Can you place the loop inside of a method and just use return?
Example:
myLoopingMethod()
{
int n = 0;
for (int i = 0; i < 50;i++)
{
n = checkStatus();
switch (n)
{
case 1:
return;
}
}
}
Another option would be to use a traditional if/else instead of a switch/case. Then you can just use break and it will jump out of your for loop
You could use a boolean.
int n = 0;
for (int i = 0; i < 50; i++)
{
bool shouldBreak = false;
n = checkStatus();
switch (n)
{
case 1:
shouldBreak = true;
break;
}
if (shouldBreak)
break;
}
I don't know if there's other logic that needs to be performed after the loop is finished, but you could try using return instead. The other option is to set a boolean flag, and exit after the switch.
switch (n)
{
case 1:
return;
}
This smells of bad design; there are a couple of ways you could fix this:
If only one condition of your switch would break the outer loop, then simply check for that before entering the switch:
if(n == 1)
break;
switch(n) { }
If multiple conditions can break the loop, refactor to a more linq style query:
Enumerable.Range(0, 50).FirstOrDefault(x => listOfBreakCodes.Contains(checkStatus());
That should call checkStatus up to 50 times until it encounters a 1 (or other break codes), and then doesnt continue evaluating elements.

Categories

Resources