"Loop" not working in C# - c#

thanks to the community here I was able to write my first program. However, I still need some help to improve the program:
Console.WriteLine("BMI Rechner");
Console.WriteLine("===========");
Console.WriteLine();
Console.Write("Körpergewicht in kg: ");
int kg;
kg = Convert.ToInt32(Console.ReadLine());
Console.Write("Größe in cm: ");
int cm;
cm = Convert.ToInt32(Console.ReadLine());
Console.Write("Geschlecht (m/w):");
string Geschlecht = Console.ReadLine();
bool Auswahl = false;
switch(Geschlecht)
{
case "m":
Auswahl = true;
break;
case "w":
Auswahl = true;
break;
default:
Console.WriteLine("Ungültige Eingabe");
Console.WriteLine("(m)ännlich/(w)eiblich");
break;
}
if (Auswahl != false) {Console.WriteLine("Eingabe wird verarbeitet");}
double BMI = kg / ( (cm / 100.0) * (cm / 100.0) );
if (BMI < 19 & Geschlecht == "w")
{ Console.WriteLine("-> Untergewicht"); }
else if (BMI >= 19 & BMI <= 24 & Geschlecht == "w")
{ Console.WriteLine("-> Normalgewicht"); }
else if (BMI > 24 & Geschlecht == "w")
{ Console.WriteLine("-> Übergewicht"); }
if (BMI < 20 & Geschlecht == "m")
{ Console.WriteLine("-> Untergewicht"); }
else if (BMI >= 20 & BMI <= 25 & Geschlecht == "m")
{ Console.WriteLine("-> Normalgewicht"); }
else if (BMI > 25 & Geschlecht == "m")
{ Console.WriteLine("-> Übergewicht"); }
Console.ReadLine();
I made a switch thingie in the middle to prevent the program from crashing if a wrong input is given. It works and I get these lines:
Console.WriteLine("Ungültige Eingabe");
Console.WriteLine("(m)ännlich/(w)eiblich");
which is supposed to be my "loop" back to the options "m" and "w". However, if I enter m/w now, the program just closes, meaning that it doesn't work at all.
Is there an error in my code or am I just using the wrong command?
I apologize for my command of the programming lingo. This is my first time.
Thanks in advance!

To be honest I don't see any loop in your code.
You could do what you say using a do...while loop as such:
do
{
//...
}while (Geschlecht != "m" && Geschlecht != "w");
The do...while loop will check after the each iteration (not before, meaning it will always enter in the loop at least once). In this case the condition says that it will loop as long as Geschlecht is not "m" and is not "w".
Applying this to your code, you will get:
//...
bool Auswahl = false;
string Geschlecht;
do
{
Console.Write("Geschlecht (m/w):");
Geschlecht = Console.ReadLine();
switch(Geschlecht)
{
case "m":
Auswahl = true;
break;
case "w":
Auswahl = true;
break;
default:
Console.WriteLine("Ungültige Eingabe");
Console.WriteLine("(m)ännlich/(w)eiblich");
break;
}
}while (Geschlecht != "m" && Geschlecht != "w");
if (Auswahl != false) {Console.WriteLine("Eingabe wird verarbeitet");}
//etc...
Please notice I have taken two variable out of the loop, those are Auswahl and Geschlecht. The reason is because both are needed to be available outside of the loop, in particular Geschlecht is needed in the conditional.
Jimmy comments that it is possible to do this in such way that Auswahl is no longer needed... here is one way to do it (as valid as any other):
//...
Console.Write("Geschlecht (m/w):");
string Geschlecht = Console.ReadLine();
while (Geschlecht != "m" && Geschlecht != "w");
{
Console.WriteLine("Ungültige Eingabe");
Console.WriteLine("(m)ännlich/(w)eiblich");
Console.Write("Geschlecht (m/w):");
Geschlecht = Console.ReadLine();
}
Console.WriteLine("Eingabe wird verarbeitet");
//etc...
In this case we have a while loop, in code inside the loop will only execute if the condition is met (that is, the condition is verified before each iteration).
You may also consider to have a different data type for Geschlecht since the only valid values it has are "m" and "w"... but I digress.
I want to suggest the entry C# Loops Constructs at dotnetperls as an introducion to the different kinds of loops in C#.

Related

C# String comparison not evaluating to true even though string value matches as expected

I have a question about the following code I have written for a C# Programming course assignment. Everything seems to be functioning correctly except for the if statement on line 31 which checks if the input string fed into a conversion method matches the requirements given in the if statement.
The logic chain of the if statements is as follows:
If the user entered less than 2 chairs, tell them they must buy at least 2 chairs.
If the user entered 2 or more chairs, proceed to next iteration of loop and check the next else if statement.
If user entered 2 or more chairs and the wood variable is not string "pine", "maple", or "oak, enter this else if block.
Give user a chance to enter a value. Acceptable values are "p", "m", and "o".
Convert single-character string to string with woodType method, which returns "pine", "maple", or "oak" based on what they input.
If user did not enter an acceptable value, return to loop after telling the user to try again.
This is where the hang-up is. If they input a valid value, the logic chain should proceed to the final else if block, but it does not. See commented line 30. Uncomment this line and it returns the name of the wood correctly from the method.
Final else if block: if everything was good, repeat the order to the user, calculate the cost, and return the final cost.
For some reason, the logic is failing at step 7 and remaining in the loop, continuously demanding the user input a valid value even though it has received a valid value. Perhaps there is something wrong with how I am comparing the strings? Obviously, there is something wrong here, but I'm unable to put my finger on it.
Here is the source code:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
public class Tables {
static int chairs = 0;
static string wood = string.Empty;
static bool run = true;
const double CHAIR_PRICE = 50.00;
static Dictionary<string, double> PRICES = new Dictionary<string, double> {
{ "pine", 250.00 },
{ "maple", 300.00 },
{ "oak", 350.00 }
};
public static void Main() {
while (run == true) {
if (chairs < 2) {
Console.WriteLine("Enter the number of chairs: ");
chairs = chairCount(Console.ReadLine());
//Console.WriteLine("{0}", chairs);//Debug
if (chairs < 2) {
Console.WriteLine("You must order at least two chairs.");
}
} else if (chairs >= 2 && (wood != "pine" || wood != "maple" || wood != "oak")) {
Console.WriteLine("Enter the type of wood - [p]ine, [m]aple, or [o]ak: ");
wood = woodType(Console.ReadLine());
//Console.WriteLine("{0}", wood);//Debug
if (wood != "pine" || wood != "maple" || wood != "oak") {
Console.WriteLine("You must enter p, m, or o for wood type.");
}
} else if (chairs >= 2 && (wood == "pine" || wood == "maple" || wood == "oak")) {
Console.WriteLine("You have ordered a {0} table with {1} chairs.", wood, chairs);
Console.WriteLine("Total price is {0}", costCalc(wood, chairs).ToString("C", new CultureInfo("en-us")));
run = false;
}
}
}
static int chairCount(string input) {
return Convert.ToInt32(input);
}
static string woodType(string input) {
if (input == "p") { return "pine"; }
else if (input == "m") { return "maple"; }
else if (input == "o") { return "oak"; }
else { return "invalid"; }
}
static double costCalc(string wood, int chairs) {
return PRICES[wood] + (chairs * CHAIR_PRICE);
}
}
This condition
(chairs >= 2 && (wood != "pine" || wood != "maple" || wood != "oak"))
is always going to be true if chairs >= 2
you mean
(chairs >= 2 && (wood != "pine" && wood != "maple" && wood != "oak"))
But this code can be made much much simpler
while(true){
Console.WriteLine("Enter the number of chairs: ");
chairs = chairCount(Console.ReadLine());
if (chairs < 2) {
Console.WriteLine("You must order at least two chairs.");
} else {
break
}
}
while(true){
Console.WriteLine("Enter the type of wood - [p]ine, [m]aple, or [o]ak: ");
wood = woodType(Console.ReadLine());
if (wood != "pine" && wood != "maple" && wood != "oak") {
Console.WriteLine("You must enter p, m, or o for wood type.");
} else{
break;
}
}
no big outer loop needed

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.

C# While loop with Multiple ||(Or) Statements not working

I have the following C# Code
int amount_guesses = 2;
int c_answer = 4;
int u_answer = 0;
Console.WriteLine("Guessing Game");
Console.WriteLine("*Hint:The number is between 1 and 5");
Console.WriteLine("*Hint:You only get 2 guesses");
while (u_answer != c_answer || amount_guesses != 0)
{
u_answer = Convert.ToInt32(Console.ReadLine());
amount_guesses = amount_guesses-1;
if (u_answer == c_answer)
{
Console.WriteLine("Well Done that is the Correct Number");
}
else
{
Console.WriteLine("Wrong Number!Try again.You have {0} trys left", amount_guesses);
}
}
Console.WriteLine("Press any key to close");
Console.ReadLine();
But it's not jumping out of the loop when the requirements in the while statement are not met.
I also tried
while ((u_answer != c_answer) || (amount_guesses != 0))
But it's still not working, I ended changing the logic to this:
int amount_guesses = 2;
int c_answer = 4;
int u_answer = 0;
Console.WriteLine("Guessing Game");
Console.WriteLine("*Hint:The number is between 1 and 5");
Console.WriteLine("*Hint:You only get 2 guesses");
while (u_answer != c_answer && amount_guesses != 0)
{
u_answer = Convert.ToInt32(Console.ReadLine());
amount_guesses = amount_guesses-1;
if (u_answer == c_answer)
{
Console.WriteLine("Well Done that is the Correct Number");
amount_guesses = 0;
}
else
{
Console.WriteLine("Wrong Number!Try again.You have {0} trys left", amount_guesses);
}
}
Console.WriteLine("Press any key to close");
Console.ReadLine();
That works fine, but I wanted to know why my code at the top where I use || does not work?
A while loop continues as long as its condition is met. In your case, you want to continue loop as long as the player hasn't guessed the number and has guesses left. You should use an && (logical AND) condition, not an ||:
while (u_answer != c_answer && amount_guesses != 0)
{
// Here ----------------^
This is a common(ish) issue when using negation in boolean logic. OR sounds like it should be right as it matches are English way of speaking, but actually AND is what you want.
I try to always write the condition testing for equality and then negate it, so instead of:
u_answer != c_answer && amount_guesses != 0
You can write:
!(u_answer == c_answer || amount_guesses == 0)
Which is the same condition.
Take a look at De Morgams Law, also more easily remembered as
Break the line, change the sign

C# program for guessing coin toss

I'm a beginner with programming so any hints would be greatly appreciated!
I'm trying to create a program where the user guesses whether a 'coin toss' will produce heads (0) or tails (1) using a random number generator and a loop as the 'coin'. The program must output the percent of correct guesses out of the total games played.
I've tried many different ways and it's far from right! It's v discouraging.
Thanks in advance for any tips!!
-C
This is basically the closest I've come:
for (numPlays = 0; ; numPlays++)
{
Console.Write("\nWrite H/h to guess Heads, T/t to guess Tails, or Q/q to quit => ");
userChoice = Convert.ToChar(Console.ReadLine());
if (userChoice == 'H' || userChoice == 'h')
{
if (compChoice == 0)
{
Console.WriteLine("\nYOU WON");
numWins++;
}
else
Console.WriteLine("\nYOU LOSE");
if (userChoice == 'Q' || userChoice == 'q')
if (compChoice == 1)
{
Console.WriteLine("\nYOU WON");
numWins++;
}
else
Console.WriteLine("\nYOU LOSE");
if (userChoice == 'q' || userChoice == 'Q')
{
percentWin = (double)(numWins / numPlays);
Console.WriteLine("\nYou won {0} out of {1} game(s) or {2:P} of the games played.", numWins, numPlays, percentWin);
}
}
}
Console.ReadKey();
}
}
I optimized your code a little bit,I hope this helps:
int numPlays = 0, numWins = 0;
int compChoice = 0;
char userChoice;
double percentWin;
Random rnd = new Random();
while (true)
{
Console.Write("\nWrite H/h to guess Heads, T/t to guess Tails, or Q/q to quit => ");
userChoice = Console.ReadKey().KeyChar;
compChoice = rnd.Next(0, 2);
if (char.ToLowerInvariant(userChoice) != 'q')
{
if (char.ToLowerInvariant(userChoice) == 'h' && compChoice == 0)
{
Console.WriteLine("\nYOU WON");
numWins++;
}
else if (char.ToLowerInvariant(userChoice) == 't' && compChoice == 1)
{
Console.WriteLine("\nYOU WON");
numWins++;
}
else
{
Console.WriteLine("\nYOU LOSE");
}
numPlays++;
}
else
{
percentWin = (double) numWins/numPlays;
Console.WriteLine("\nYou won {0} out of {1} game(s) or {2:P} of the games played.", numWins, numPlays, percentWin);
break;
}
}
I think you don't need an explanation, all of the code is self-explanatory.But you have an obvious mistake when you calculating the percentage:
percentWin = (double)(numWins / numPlays);
Here you are performing an integer division,then casting that result to double,it's pointless because you already lose your decimal points.Instead you should cast one of the operands to double so it will perform a double division and you will get the correct result.
Just invoke this method and play your game!
public static void SomeMethod()
{
Console.Write("\nWrite H/h to guess Heads, T/t to guess Tails, or Q/q to quit => ");
char userChoice;
int numWins = 0;
int numPlays = 0;
double percentWin = 0d;
while ((userChoice = Convert.ToChar(Console.ReadLine())).ToString().ToLower() != "q")
{
numPlays++;
int compChoice = new Random().Next(2);
if (userChoice == 'H' || userChoice == 'h')
{
if (compChoice == 0)
{
Console.WriteLine("\nYOU WON");
numWins++;
}
else
{
Console.WriteLine("\nYOU LOSE");
}
continue;
}
if (userChoice == 'T' || userChoice == 't')
{
if (compChoice == 1)
{
Console.WriteLine("\nYOU WON");
numWins++;
}
else
{
Console.WriteLine("\nYOU LOSE");
}
continue;
}
}
if (numPlays != 0)
{
percentWin = (double)numWins / numPlays;
}
Console.WriteLine("\nYou won {0} out of {1} game(s) or {2:P} of the games played.", numWins, numPlays, percentWin);
Console.ReadKey();
}
This should not be any difficult, you just need to make a clear algorithm
Let me suggest one
Char playOrExit= 'y'
Int32 gameCount = 0;
Int32 Wins = 0;
While (playOrExit.ToUpper.Equals('Y'))
{
Console.Write("Press Y to continue playing and N to exit");
playOrExit = Convert.ToChar(Console.ReadLine());
//Computer choice will be math.random from 0 and 1
//now take user choice
//compare and show if he won or lost
}
if(gameCount >0)
{
Console.WriteLine("\nYou played {0} times, out of which {1} game(s) were won.", gameCount,Wins);
}

the switch case block after final score is outputed, is not compiling [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
it doesnt show the IQ result after the final score has been shown. please help. this is the full program...i used an arrow to show the switch block that refuses to compile
class Class1
{
public static int attempt, sum, AptScore, GenScore, MathScore, EngScore, bonus, TotalScore, FinalScore, choice = 0;
public static string ans;
static void Main(string[] args)
{
int FinalCount, AptCount = 0, EngCount = 0, MathCount = 0, GenCount = 0;
Console.WriteLine("Welcome to Salisbury University IQ Test game \n=====================================");
Console.WriteLine();
Console.WriteLine("How many times have you attempted this test?");
attempt = Convert.ToInt32(Console.ReadLine());
while (true)
{
if (attempt > 1)
{
Console.WriteLine("You cannot take this test");
break;
}
while (true)
{
FinalCount = AptCount + EngCount + MathCount + GenCount;
if (FinalCount < 4)
{
Console.WriteLine("Salisbury University IQ Test game \n========================================");
Console.WriteLine("Press \n1. Aptitude \n2. English. \n3. Math \n4. Gk \n5. Exit");
choice = Convert.ToInt32(Console.ReadLine());
switch (choice)
{
case 1:
if (AptCount > 0)
{
Console.WriteLine("THIS QUESTION HAS BEEN ATTEMPTED!!!");
Console.WriteLine();
continue;
}
Console.WriteLine(" What was the name of the lebanon tyrant who ruled for years unending before he was toppled due to civil war? \nA. Osama Bin laden \nB. Gaddafi \nC. Jonathan ");
ans = Console.ReadLine();
if (ans == "B" || ans == "b")
{
AptScore += 10;
}
AptCount++;
continue;
case 2:
if (EngCount > 0)
{
Console.WriteLine("THIS QUESTION HAS BEEN ATTEMPTED!!!");
Console.WriteLine();
continue;
}
Console.WriteLine(" What is the antonym of Pleasure? \nA. Pain \nB. Ecstacy \nC. Wonder");
ans = Console.ReadLine();
if (ans == "A" || ans == "a")
{
EngScore += 10;
}
EngCount++;
continue;
case 3:
if (MathCount > 0)
{
Console.WriteLine("THIS QUESTION HAS BEEN ATTEMPTED!!!");
Console.WriteLine();
continue;
}
Console.WriteLine(" What is the sum of 435 and 345? \nA. 799 \nB. 780 \nC. 600 ");
ans = Console.ReadLine();
if (ans == "B" || ans == "b")
{
MathScore += 10;
}
MathCount++;
continue;
case 4:
if (GenCount > 0)
{
Console.WriteLine("THIS QUESTION HAS BEEN ATTEMPTED!!!");
Console.WriteLine();
continue;
}
Console.WriteLine(" What year did Nigeria become a republic? \nA. 1960 \nB. 1963 \nC. 1990 ");
ans = Console.ReadLine();
if (ans == "B" || ans == "b")
{
GenScore += 10;
}
GenCount++;
continue;
case 5:
Environment.Exit(0);
break;
default:
Console.WriteLine("You entered an invalid number");
continue;
} // end of switch
break;
} // end of inner while loop
break;
} // end of else
break;
} // outer loop end
if (attempt < 5 && attempt != 0)
{
TotalScore = MathScore + GenScore + EngScore + AptScore;
Console.WriteLine("Your total score is : " + TotalScore);
if (TotalScore == 10)
{
Console.WriteLine(" You have no Bonus point ");
}
else if (TotalScore == 20)
{
bonus += 2;
Console.WriteLine("Your Bonus is {0}", bonus);
}
else if (TotalScore == 30)
{
bonus += 5;
Console.WriteLine("Your Bonus is {0}", bonus);
}
else if (TotalScore == 40)
{
bonus += 10;
Console.WriteLine("Your Bonus is {0}", bonus);
}
FinalScore = TotalScore + bonus;
Console.WriteLine("Your finalscore is : " + FinalScore);
**it refuses to compile this switch block -->** switch (FinalScore)
{
case 10:
if (FinalScore >= 10)
{
Console.WriteLine("Your IQ level is below average");
}
break;
case 22:
if (FinalScore >= 22)
{
Console.WriteLine("Your IQ level is average");
}
break;
case 35:
if (FinalScore >= 35)
{
Console.WriteLine("You are intelligent");
}
break;
case 40:
if (FinalScore == 40)
{
Console.WriteLine("You are a genius");
}
break;
default:
break;
} // end of last s1witch case
}// end of if statement
} // end of main method */
} // end of class
Its always better to use if/else for your particular case, With switch statement you can't put conditions in the case. It looks like you are checking for ranges and if the range is constant then you can try the following
if (FinalScore == 40)
{
Console.WriteLine("You are a genius");
}else if (FinalScore >= 35)
{
Console.WriteLine("You are intelligent");
}else if (FinalScore >= 22)
{
Console.WriteLine("Your IQ level is average");
}else if(FinalScore >= 10)
{
Console.WriteLine("Your IQ level is below average");
}else
{
// something else
}
You should use If else statements for what you are trying to do and you could shorten your code a whole lot by making use of ternary statements like so,
Console.WriteLine((FinalScore >= 40) ? "You are a genius" :
(FinalScore >= 35) ? "You are intelligent" :
(FinalScore >= 22) ? "Your IQ level is average" :
(FinalScore >= 10) ? "Your IQ level is below average" : "You are really below average");
//The really below average would be your something else referenced above.
Your code compiles just fine.
If you logged the default case of that switch block, you would've seen that 40 is effectively an unreachable case. Your formula guarantees that 40 is never generated -- all 4 correct is 50 points due to the bonus points. All incorrect would also never yield a result.
The valid cases are: 0, 10, 22, 35, 50. You only account for 10, 22, & 35.
default:
// this would've thrown an exception for FinalScore==50
throw new Exception("unexpected score of " + FinalScore);

Categories

Resources