How to skip while in do while loop? - c#

The problem is that I cant write do while loop without while part ... can I skip it somehow or .. ?
// 9. Keep adding numbers untill you add number 7 twice in a row .
int a;
int b;
do
{
Console.WriteLine("add number:");
a = int.Parse(Console.ReadLine());
Console.WriteLine("add number:");
b = int.Parse(Console.ReadLine());
if (a == 7 && b == 7)
{
break;
Console.WriteLine("end");
}
}

The best way to do this would be to have the condition in your while
while(a != 7 || b != 7)
{
Console.WriteLine("add number:");
a = int.Parse(Console.ReadLine());
Console.WriteLine("add number:");
b = int.Parse(Console.ReadLine());
}
Console.WriteLine("end");
This will make the loop automatically terminate when it finds that both values are 7
As per #AlexK's answer, you could also make the while have no condition, and just contain true
while(true)
{
Console.WriteLine("add number:");
a = int.Parse(Console.ReadLine());
Console.WriteLine("add number:");
b = int.Parse(Console.ReadLine());
if (a == 7 && b == 7)
{
break;
Console.WriteLine("end");
}
}
This will do the same as the above code, though instead of checking if the values are 7 at the beginning of each loop, it instead will loop infinitely until manually exited inside the loop
You may also notice that the syntax I have used is
while(/*condition*/)
{
//code here
}
This is a shorter version of the syntax that you are using, though it acts slightly differently. While the above code sample will never run any code if the condition isn't met when the loop is entered, the below code
do
{
//code here
}
while(/*condition*/);
Will always run the code contained inside the do at least once, regardless of whether the condition is met or not

You have two possibititles. Either set your condition directly to the while-part as Alfie already said or use an infinite loop. This is in particular usefull if you have more than one exit-path for your loop, for instance:
while(true)
{
if(a == 3) break;
if(b == 7) break;
// some more code
}
Of course this code is quite contrived and could easily be replaced by if(a == 3 || b == 7) break but sometimes you can´t (or don´t want to) combine all your conditions into one single. Furthermor this could be usefull if you want to break iteration on some condition but continue on another (to reduce nesting of your code for example).

Related

How to return to a specific point int the code without having to use goto?

So I wrote a lottery program.
The program works as the following:
the user inputs 6 numbers ranging from 1 to 46.
the program chooses 6 numbers ranging from 1 to 46.
the program compares the arrays for matching numbers.
the program shows the user how many matching number he got right and also if he won the lottery or not.
end
now , I want to add an option to the user , if the user wants to try again he can just press Y and the program will jump him to the point where he inputs numbers.
But , I don't know how to achieve that without using goto, I don't want to use goto because I know it's bad practice to use it.
Would love to get some recommendations.
I know that I am still missing the N portion of the code, but I just wanted to show what I've tried so far.
char tryAgain;
if (gamelost || gamewon == true)
{
tryAgain = 'Y';
Console.WriteLine("Do you want to try again? Y/N");
tryAgain = char.Parse(Console.ReadLine());
if (tryAgain == 'Y')
{
goto gameAgain;
}
else
{
return;
}
}
}
Use a loop. You need to check the only condition upon which you exit the loop. Note that this code doesn't sanitize user's input.
using static System.Console;
void do_lottery()
{
while (true)
{
Write("Enter 6 digits, divided by comma: ");
var input = ReadLine();
var user_numbers = input.Split(",").Select(n => int.Parse(n));
var numbers_to_guess = new[] { 6, 23, 12, 46, 8, 2 };
if (user_numbers.All(n => numbers_to_guess.Any(z => z == n)))
{
WriteLine("You won!");
}
else
{
WriteLine("You lose!");
}
Write("Do you wanna play once again? (Y/N): ");
var answer = ReadLine().ToUpper();
if (answer != "Y") break; //Exit loop
}
WriteLine("Lottery finished.");
}

How to correctly implement while logic

I am writing a method to take user input for a menu with three options: 1,2,3. My do while loop runs, however my while logic is still accepting unwanted input. Why is my code not looping for inputs outside of my set range of values?
I have tried different logical operators, removing logical operators and setting while Option < Value.
private static MenuOption ReadUserOption()
{
int Option;
Console.WriteLine("Please make a selection");
Console.WriteLine("1, will run TestName, 2 will run Guess that number, 3 Wil quit the program.");
do
{
Option = Convert.ToInt32(Console.ReadLine());
return (MenuOption)(Option - 1);
} while (Option < 1 || Option > 3);
}
My goal is for any user input outside of <1 and >3 for the loop to continue until a value within that range is entered. In its current state if I enter 0 the loop will accept that value and output -1.
You just need to move the return statement outside the loop
private static MenuOption ReadUserOption()
{
int Option;
Console.WriteLine("Please make a selection");
Console.WriteLine("1, will run TestName, 2 will run Guess that number, 3 Wil quit the program.");
do
{
Option = Convert.ToInt32(Console.ReadLine());
} while (Option < 1 || Option > 3);
return (MenuOption)(Option - 1);
}

Cant get while loop to check if my userinput equals some numbers

This is the piece of code I am talking about. So I want the user only to be able to write 1 or 2 or else the while loop will never break. The problem is that for some reason the loop just never breaks, even if I write 1 or 2.
while (caseSwitch != 1 || caseSwitch != 2)
{
Console.Write("Please write a number: ");
Int32.TryParse(userInput = Console.ReadLine(), out caseSwitch);
}
caseSwitch has an any time only a single value so it will always be either not 1 or not 2. Replace || with &&. Meaning you loop as long as caseSwitch is not 1 and is not 2. The moment it is one of them it halts.
while (caseSwitch != 1 && caseSwitch != 2)
{
Console.Write("Please write a number: ");
Int32.TryParse(userInput = Console.ReadLine(), out caseSwitch);
}
Note: there is another solution to this problem using De Morgan's law.
while (!(caseSwitch == 1 || caseSwitch == 2))
{
Console.Write("Please write a number: ");
Int32.TryParse(userInput = Console.ReadLine(), out caseSwitch);
}

c# cant run two functions in a loop?

What i want to do is to make it that inside a loop, the computer checks whether the number entered is firstly not a decimal, and at the same time i want to make sure that the number is within the range 1 - 100. My code now works in regards to having the first function about the number not being a decimal, so when i enter a decimal, an error message is displayed that tells the user to keep adding another number until an integer is added, and it then runs to the next part. However it doesn't seem to work when i put in a number outside of the range, the error message doesn't pop up and the conditions just don't seem to work. What i want to know is how do i get these two parts, the decimal and the range checking to work simultaneously. I'm really new to coding so could any explanations be simple so that i could understand. Thank you in advance!
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = int.TryParse(inputcost, out validcost);
while (!int.TryParse(inputcost, out validcost))
{
if (result == true )
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("You Cannot Enter Decimals. Please Enter A Valid Integer Value.");
Console.WriteLine();
inputcost = Console.ReadLine();
}
if (validcost < 100 && validcost > 1)
{
Console.Write("valid value");
}
else
{
Console.Write("invalid value.please enter a number between 1 and 100 ");
Console.ReadLine();
}
}
The line
while (!int.TryParse(inputcost, out validcost))
means that you enter the while loop only when the user types something that cannot be converted to an integer. If it is a valid integer the code inside the while loop is never reached and thus, your test on the valid range is never executed
Instead put everything inside the an infinite loop and provide a way to break the program (type x to quit)
while (true)
{
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: (type x to quit)");
inputcost = Console.ReadLine();
// Check if the user wants to stop executing the program
if(inputcost == "x")
break;
// Check if it is a valid integer
bool result = int.TryParse(inputcost, out validcost);
if (!result)
{
Console.WriteLine("You Cannot Enter Decimals (or strings). Please Enter A Valid Integer Value.");
}
else if (validcost > 100 || validcost < 1)
{
Console.WriteLine("invalid value.please enter a number between 1 and 100 ");
}
else
{
Console.WriteLine("Valid value");
// other code block that works with the input number....
}
}
Alternativly use another condition for your loop, something that first checks for an integer and afterwards if it is in range:
while (!int.TryParse(inputcost, out validcost)) || validCost < 1 || validCost > 100)
{
Console.WriteLine("Please enter an integer between 1 and 100");
inputCost = Console.ReadLine();
}
All the code that should be executed when your inout is valid should now gow beyond the loop, not inside it.

building a FOR loop with several IF's and causing it to stop only in some runs

I have a 2D array which some of it's members are numbers (playerID -1,2,3,4 etc.)and the rest are zeros.
I want to make a for loop containing all kinds of check methods that goes through the the loop and returns an answer. the checks are ranked, so that when one of the higher checks is returned TRUE, the loop for that playerID can terminate. Later on I want to use the check results to compare between the players, but first thing's first - I can't get the big FOR loop running.
I had in mind something like this:
for (int playerID = 1; playerID <= participants; playerID++)
{
checkA = Check4forsequenceof4(matrix); //method A
if (checkA == 0)
continue;
else
Console.WriteLine(p + "completed check A");
break;
if (checkB == 0)
continue;
else
Console.WriteLine(p + "completed check B");
break;
if (checkC == 0)
continue;
else
Console.WriteLine(p + "completed check C");
break;
}
Problems are: the break breaks out of the FOR loop instead of only from the if, and I can't think of how to check for the next playerID, and also can't figure out how best to store the results for every player for later display.
First off, if you want to make this work, you can't rely on indentation - you need braces:
if (checkA == 0)
continue;
else
{
Console.WriteLine(p + "completed check A");
break;
}
This will solve your immediate problem of the loop immediately breaking out.
That being said, given the above check, you'll NEVER check for B. I suspect you want to invert your logic, as such:
if (checkA != 0)
{
Console.WriteLine(p + "completed check A");
break;
}
This will cause checkA to run, then checkB, etc.
You have a much bigger problem. Your code reads:
checkA = Check4forsequenceof4(matrix); //method A
if (checkA == 0)
continue;
else
Console.WriteLine(p + "completed check A");
break;
That will always break out of the loop the first time checkA is not 0. So checkB will never be executed.
I'm not sure what you're trying to do. The indentation of your code indicates that the break isn't necessary anywhere, since the default is tao fall through (which I think is what you want to do).
var allPlayers = new List<Player>();
// Fill the list allPlayers here.
var validPlayers = new List<Player>();
foreach (Player p in allPlayers) {
if(CheckA(p) || CheckB(p) || CheckC(p)) {
validPlayers.Add(p);
}
}
Note: c# performs a so called shortcircuit evaluation. I.e. if CheckA returns true the others will not be evaluated any more. If CheckB returns true, then CheckC will not be evaluated. By the way "||" is a logical OR. If all checks have to be OK then use the logical AND "&&" instead. Here c# will stop checking as soon as a check fails.
If you are only interested in which check has returned true first, then only use "continue" when the check is OK, but no "break" otherwise.
My answer might not be very appropriate, but I am not really sure what you are trying to do.
I think this is what you're looking for. Though I don't know when checkB or C is supposed to be set. After the checkA check?
for (int playerID = 1; playerID <= participants; playerID++)
{
checkA = Check4forsequenceof4(matrix); //method A
if (checkA == 0)
continue;
Console.WriteLine(p + "completed check A");
if (checkB == 0)
continue;
Console.WriteLine(p + "completed check B");
if (checkC == 0)
continue;
Console.WriteLine(p + "completed check C");
}
unless I misunderstand your question:
for (int playerID = 1; playerID <= participants; playerID++)
{
checkA = Check4forsequenceof4(matrix); //method A
if (checkA != 0)
Console.WriteLine(p + "completed check A");
else
continue;
if (checkB != 0)
Console.WriteLine(p + "completed check B");
else
continue;
if (checkC != 0)
Console.WriteLine(p + "completed check C");
else
continue;
}
Restructure your if statements...
if (0 != checkValue) {
Console.WriteLine(p + " completed check X");
Continue;
}
So this will cause the loop to go into the next iteration when a check value is non-zero.
There is no such thing as breaking out of an if statement.
I came up with the following code.
// This store all of the checks formed as Fun<Player, bool> delegates.
var checks = new List<Func<Player, bool>>();
checks.Add(x => DoesPlayerSatisfyCheck1(x));
checks.Add(x => DoesPlayerSatisfyCheck2(x));
checks.Add(x => DoesPlayerSatisfyCheck3(x));
// Add more checks here if necessary.
// This stores all players who have passed a check.
// The first check that passed will be associated with that player.
var results = new Dictionary<Player, int>();
// Loop through all players.
foreach (Player p in participants)
{
// Now perform each test in order.
for (int i = 0; i < checks.Count; i++)
{
Func<Player, bool> checker = checks[i];
if (checker(p))
{
results.Add(p, i);
break;
}
}
}
After this code executes the results data structure will contain an entry for each Player that passed one of the checks. That entry will also contain the check number. If you want to add more checks later you can simply add it to the checks data structure.
This code does not behave the same as what you posted. But, it does behave per the requirement you gave; as best I can tell anyway.

Categories