switch while won't loop - c#

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
{
}
}

Related

how to stop my code from looping at the end?

i'm new at coding C# pls help me fix this simple dice game, it keeps on looping at the end of the game
** apparently how i think is that in the end of this code something makes the NO commend on looping and getting re runed**
using System;
namespace first_game
{
class Program
{
static void Main(string[] args)
{
string userName;
userName = Console.ReadLine();
#region
{
int userPoint = 0;
int cpuPoint = 0;
int pDice;
bool closeApp;
while (true)
{
while (cpuPoint < 10 && userPoint < 10)
{
Random rd = new Random();
pDice = rd.Next(1, 6);
#endregion
int P2Dice;
Random scondRd = new Random();
P2Dice = scondRd.Next(1, 6);
Console.ReadLine();
Console.WriteLine("-------------------");
Console.Write("playe dice:");
Console.WriteLine(pDice);
Console.Write("CPU dice:");
Console.WriteLine(P2Dice);
Console.ReadLine();
if (pDice > P2Dice)
{
userPoint = userPoint + 1;
}
else if (pDice < P2Dice)
{
cpuPoint = cpuPoint + 1;
}
Console.Clear();
Console.WriteLine(userName);
Console.Write("player point:");
Console.WriteLine(userPoint);
Console.Write("CPU point:");
Console.Write(cpuPoint);
Console.ReadLine();
}
if (userPoint == 10)
{
Console.WriteLine("-----------------\nYOU WIN!!!");
Console.ReadLine();
}
else
{
Console.WriteLine("-----------------\nYOU lost!!! LOL");
Console.ReadLine();
}
Console.WriteLine("wanna continue?\n press Y for yes press N for NO");
ConsoleKeyInfo sw;
sw = Console.ReadKey();
Console.Clear();
if (sw.Key == ConsoleKey.Y)
{
userPoint = 0;
cpuPoint = 0;
continue;
}
else if (sw.Key == ConsoleKey.N)
{
}
else
Console.WriteLine("ERROR!");
}
}
}
}
}
You seem to have the wrong idea about continue. A while loop always (given a true condition) reruns if it reaches the end, a continue just starts the next iteration early.
else if (sw.Key == ConsoleKey.N) { }
else Console.WriteLine("ERROR!");
This is where you should exit the loop, for example using a break
else if (sw.Key == ConsoleKey.N) {
break;
} else Console.WriteLine("ERROR!");
Add a break to exit the while loop:
if (userPoint == 10)
{
Console.WriteLine("-----------------\nYOU WIN!!!");
break;
}
else
{
Console.WriteLine("-----------------\nYOU lost!!! LOL");
break;
}
Then add this after the while loop, so that the console doesn't close:
Console.ReadLine();

How do you pause between cases in switch statements? c#. 3second delay before executing the next case

This is a sample of my code. I want to have a 3 second delay before executing the next case (display picturebox). But When I tried using timer/stopwatch, the 3 second delay will only be on the 1st case and case2 will execute the same time as case1 (with no delay).
private void button1_Click(object sender, EventArgs e)
{
string input = (input1.Text).ToString();
char[] letters = input.ToCharArray();
int stringlength = letters.Length;
int length = stringlength - 1;
int state = 1;
int position = 0;
string validation = " ";
switch (state)
{
case 1:
//insert timer here
if (letters[position] == 'a')
{
pictureBox2.Visible = true;
validation = "Invalid";
label1.Text = validation;
break;
}
else if (letters[position] == 'b')
{
if (position == length)
{
validation = "Invalid";
label1.Text = validation;
break;
}
pictureBox2.Visible = true;
position = position + 1;
goto case 2;
}
break;
case 2:
//Insert Timer here
if (letters[position] == 'a')
{
pictureBox3.Visible = true;
if (position == length)
{
validation = "Invalid because it does not end at final state";
label1.Text = validation;
break;
}
position = position + 1;
goto case 3;
}
else if (letters[position] == 'b')
{
if (position == length)
{
validation = "Invalid";
label1.Text = validation;
break;
}
position = position + 1;
goto case 4;
}
break;
}
}
By the way, I can't use Task.Delay or async/await because I use the .Net 4.0 framework.
You can perform this by using:
System.Threading.Thread.Sleep(3000);
So Your code should look like:
private void button1_Click(object sender, EventArgs e)
{
int state = 1;
//some code
switch (state)
{
case 1:
System.Threading.Thread.Sleep(3000);
//some case code
break;
case 2:
System.Threading.Thread.Sleep(3000);
//some case code
break;
default:
System.Threading.Thread.Sleep(3000);
//some default code
break;
}
//rest of the code
}
Just to let You know, there should be other (and better) way to going through this, rather than using switch and this type of GOTO case this and this. Making the code unreadable in future.
Thread.Sleep(3000) you can use

How to make "for" with stop?

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;
}
}
}

Having an issue calling methods from another class

I'm having an issue with calling methods from another class in C#. I haven't been doing this long (3 weeks to be exact) and don't get the ideas behind calling methods. I have declared everything as public to try to make it easier but it isn't working for me just yet. Any help at all would be very much appreciated. Here is the code in question, I want to use a method in an if statement to calculate the area of various simple shapes however at the output stage I get "That is not a valid choice"
namespace Area_Calculator
{
public class Area
{
public static int Square(int side)
{
int i, A;
Console.WriteLine("Please enter the length of the side of the square");
i = Convert.ToInt16(Console.ReadLine());
A = i * i;
return A;
}
public static int Rectangle(int width, int height)
{
int i, j, A;
Console.WriteLine("Please enter the width of the rectangle");
i = Convert.ToInt16(Console.ReadLine());
Console.WriteLine("Please enter the height of the rectangle");
j = Convert.ToInt16(Console.ReadLine());
A = i * j;
return A;
}
public static double Triangle(int width, int height)
{
double i, j, A;
Console.WriteLine("Please enter the width of the triangle");
i = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Please enter the height of the triangle");
j = Convert.ToDouble(Console.ReadLine());
A = (.5 * i * j);
return A;
}
public static double Circle(int radius)
{
int i;
double A;
Console.WriteLine("Please enter the radius of the circle");
i = Convert.ToInt16(Console.ReadLine());
A = (i * Math.PI);
return A;
}
}
class Program
{
static void Main(string[] args)
{
int x, i, j;
i = 0;
j = 0;
Console.WriteLine("Please select what type of shape you wish to find the area of:\n1. Square\n2. Rectangle\n3. Triangle\n4. Circle\n");
x = Convert.ToInt16(Console.ReadLine());
Area r = new Area();
if (x == 1)
{
Area.Square(i);
}
if (x == 2)
{
Area.Rectangle(j, i);
}
if (x == 3)
{
Area.Triangle(j, i);
}
if (x == 4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
Console.ReadKey();
}
}
}
You'll currently always see "That is an invalid choice" unless x is 4... because the final if/`else is disconnected from all the rest.
You could change it to use else if everywhere, like this:
if (x == 1)
{
...
}
else if (x == 2)
{
...
}
else if (x == 3)
{
...
}
else if (x == 4)
{
...
}
else
{
...
}
... but it would be simpler to use a switch statement:
switch (x)
{
case 1:
...
break;
case 2:
...
break;
case 3:
...
break;
case 4:
...
break;
default:
...
break;
}
That better expresses your intention of "I want to execute exactly one of these branches, based on a simple selection on x, with a "default" branch if x isn't any of the known values."
Your main issue is, what others have mentioned, about the if statements. Another thing is that you calculate the area but never print it out.
if (x == 1)
{
Console.WriteLine(Area.Square(i));
}
else if (x == 2)
{
Console.WriteLine(Area.Rectangle(j, i));
}
else if (x == 3)
{
Console.WriteLine(Area.Triangle(j, i));
}
else if (x == 4)
{
Console.WriteLine(Area.Circle(i));
}
else
{
Console.WriteLine("That is an invalid choice");
}
Initially, you have to change a bit your if statements, like below:
if (x == 1)
{
Area.Square(i);
}
else if (x == 2)
{
Area.Rectangle(j, i);
}
else if (x == 3)
{
Area.Triangle(j, i);
}
else if (x == 4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
Doing so, you will get the message that you get know in all cases, where x is not 4, also in the rest cases 1, 2 and 3.
Your code is checking if x equals 4, otherwise using the code in the else block.
This will be run every time unless x=4!
Try this instead:
x = Convert.ToInt16(Console.ReadLine());
Area r = new Area();
if (x == 1)
{
Area.Square(i);
}
else if (x==2)
{
Area.Rectangle(j, i);
}
else if (x == 3)
{
Area.Triangle(j, i);
}
else if (x==4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
or even better:
x = Console.ReadLine();
switch x
{
case "1":
Area.Square(i);
break;
case "2":
Area.Rectangle(j, i);
break;
case "3":
Area.Triangle(j, i);
break;
case "4":
Area.Circle(i);
break;
default:
console.WriteLine("That is an invalid choice");
break;
}
The problem is with your if statement, you need to be using else if instead of if:
if (x == 1)
{
Area.Square(i);
}
else if (x==2)
{
Area.Rectangle(j, i);
}
else if (x == 3)
{
Area.Triangle(j, i);
}
else if (x==4)
{
Area.Circle(i);
}
else
{
Console.WriteLine("That is an invalid choice");
}
The issue when using if is that it got to the very last if and the else was true, so it would print "That is an invalid choice".
And some notes on your implementation...
In your main program, its unnecessary to have an Area object, Area r = new Area(), since you don't use r anywhere.
All of the methods in Area take in values (which you pass in) but then completely ignore them and ask for the values again. I would either remove the parameters from the methods, or ask the user in the main program and pass in the values. The input logic can be put inside the if statement for each different calculation. Last, you don't do anything with the return value of the function, so you don't display the area to the user. You need to edit your functions to write it to the console, for example:
Console.WriteLine("The square area is {0}", Area.Square());
Inside the if statement, or because you are doing user input in the calculation, you could have a similar line in each Area method.
enum AreaEnum
{
Square,
Rectangle,
Triangle,
Circle,
};
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please select what type of shape you wish to find the area of:\n1. Square\n2. Rectangle\n3. Triangle\n4. Circle\n");
int x = Convert.ToInt16(Console.ReadLine());
AreaEnum myValueAsEnum = (AreaEnum)x;
Calculate(myValueAsEnum);
}
static double Calculate(AreaEnum a)
{
int x, i, j;
i = 0;
j = 0;
Area area = new Area();
switch (a)
{
case AreaEnum.Square:
{
return Area.Square(i);
}
case AreaEnum.Rectangle:
{
return Area.Rectangle(j, i);
}
case AreaEnum.Triangle:
{
return Area.Triangle(j, i);
}
case AreaEnum.Circle:
{
return Area.Circle(i);
}
default:
{
Console.WriteLine("That is an invalid choice");
return 0;
}
}
}
}

Using a for loop inside switch/case

Can I use a for loop inside a switch/case?
Example code:
String[,] drinks = new String[,] { { "Cola", "20" }, { "Fanta", "20" }, { "Sprite", "20" }, { "Tuborg", "25" }, { "Carlsberg", "25" } };
switch (menuChoice)
{
case 0:
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
break;
for (int i = 0; i < drinksCount; i++)
{
case i+1:
buyDrink(drinks[i,0];
break;
}
(More code and methods is in between these)
Basically, I create an array with the drinks this machine sells, and then I want to create a menu where to chose these drinks, but also the ability to add more drinks within the GUI.
Is this even possible?
You can use loops inside switch statement but not the way you are using it currently. Try to replace your code with below code:
if (menuChoice == 0)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else if (menuChoice > 0 && menuChoice < drinksCount)
{
buyDrink(drinks[menuChoice, 0]);
}
ADDED:
As per valuable comments, why don't you just use -1 as menuChoice for Exit, this way:
if (menuChoice == -1)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else if (menuChoice > 0 && menuChoice <= drinksCount)
{
buyDrink(drinks[menuChoice - 1, 0], Convert.ToDouble(drinks[menuChoice - 1, 1]));
}
This way you can call your static method as shown:
static void buyDrink(String drink, double drinkPrice)
A better title for this question might be: Is it possible to have variable case statements?
case i+1:
This is an invalid case statement. A the value of a case statement must be a constant. If i were a constant in this case, it would be allowed. However, i isn't, and therefore the case statement will not compile.
Having said that, although the answer to the title question is yes, as shown by other answers, the real answer here is: Not the way you're trying to do it.
It doesn't make sense to have code after break.
You break from the case how do you expect it to execute?
case 0:
{
break;//If you break here, it exits the block.. your loop never executes
for (int i = 0; i < drinksCount; i++)
{
case i+1:
buyDrink(drinks[i,0];
break;
}
}
And even if it is possible I fail to see the point.
You will execute the case as long as it is greater than 0 right?
So why not just use an if statement, help yourself and others?
if(menuChoice ==0)
{
//dosomething
}
else if(menuChoice >0)
{
//buy drink
}
if(menuChoice == 0) {
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
} else if(menuChoice > 0 && menuChoice <= drinksCount) {
buyDrink(drinks[menuChoice - 1, 0]);
}
That code could not work at all.
A break is the final (and required) statement of a case.
Looking at your example you could simply write
if(menuChoice == 0)
{
Console.WriteLine("Goodbye!");
Thread.Sleep(500);
Environment.Exit(0);
}
else
{
buyDrink(drinks[menuChoice-1,0]);
}
EDIT: Seeing your comment about buyDrink as static method and the parameters required then you should change the call to buyDrink prepending the class name where the buyDrink method is defined and add the parameter for the price (as double value)
.......
else
{
BeverageClass.buyDrink(drinks[menuChoice-1,0], Convert.ToDouble(drinks[menuChoice-1,1]));
}

Categories

Resources