attempting to loop inside a switch - c#

I have a menu with option.
Option 1: BMI caculator (option 1/case 1)
When entering the details in BMI calculator such as Height in Meters I am trying to get it to loop back and print an error message and ask again if the height that the user entered isn't a int (meters) for example if the user inputs a string say "M" it will not work and loops back to the initial question prompting for input IE: 2.1. I'm trying to use IF ELSE inside the switch/case. You can see in height section I can use goto case 1 to loop it but does not work for weight ( because that will go back to the beginning of case 1 and user would need to enter height again), Whatever the outcome of weight I need to keep the result of Height prior to weight so as to perform the final calculation BMI = . Sorry if this isn't clear, I'm really new and really stuck.
switch (optionsIn)
case 1:
{
Console.Clear();
Console.WriteLine("What is your height in meters");
double heightMax = 0.00;
string heightMeters = Console.ReadLine();
double.TryParse(heightMeters, out double heightM);
if (heightMax < heightM)
{
Console.Clear(); // nothing needs to run here , just clear to look better and move to collection of weight.
}
else
{
Console.Clear();
Console.WriteLine("Incorrect option try again");
Console.WriteLine("press enter to try again");
Console.ReadKey();
goto case 1; // better way to do it rather than goto case 1?
}
Console.WriteLine("Enter weight in Kgs"); // need to start here if incorrect input from user
double kgs = 00.00;
string weight = Console.ReadLine();
double.TryParse(weight, out double weightKgs);
if (kgs < weightKgs)
{
Console.Clear(); // nothing needs to run here , just clear console to look neat and move to calculating and printing BMI
}
else
{
Console.WriteLine("Incorrect option try again"); // cannot get to loop back to Enter weight
Console.WriteLine("press enter to return");
Console.ReadKey();
break;
}
double bmi = weightKgs / (heightM * heightM);
Console.WriteLine($"BmI is " + bmi);
Console.WriteLine("press any key to exit");
Console.ReadKey();
break;
}

I suggest method extraction:
public static double ReadDouble(string title, Func<double, bool> validation) {
// Keep Asking User until correct value is provided
while (true) {
// Show title if we have it
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
if (!double.TryParse(Console.ReadLine(), out double result))
// Not a double value at all; say, "bla-bla-bla"
Console.WriteLine("Syntax error. Please, try again.");
else if (validation != null && !validation(result))
// Not a valid double value, say, 123456.89 kg weight
Console.WriteLine("Not a valid value. Please, try again.");
else
return result;
}
}
then you can easily use it within switch \ case:
double heightM = ReadDouble("What is your height in meters", m => m > 0.3 && m < 3.0);
double weightKgs = ReadDouble("Enter weight in Kgs", m => m > 0.7 && m < 700.0);
double bmi = weightKgs / (heightM * heightM);
Console.WriteLine($"BmI is {bmi:F1}");

Instead of using goto - which is considered bad practice and is not all that much readable, try using a while or do/while loop instead.
Something like:
string input;
double heightMax = 0.0;
do {
input = Console.ReadLine();
double.TryParse(input, out double heightM);
Console.Clear();
} while (heightMax >= heightM);
Also, consider using functions for loading the data. Maybe you can think of some way of generalizing so that you can have only one function that you can reuse for all the stuff you need to load.

Related

While loop breaks unintentionally

I am in my second week of C# training, so I am pretty new to programming. I have to make a program that returns the smallest integer out of a series of random integer inputs. Once the input = 0, the program should break out of the loop. I am only allowed to use while and for loops. For some reason my program breaks out of loop after the second input and it looks like it doesn't even care if there is a "0" or not. Could you please see where I went wrong? I have been busting my head off with this. Sorry if this question has already been posted by somebody else but I did not find an answer to it anywhere.
PS: The zero input should be taken into account for the comparison.
So this is what I've got so far:
class Program
{
static void Main()
{
int i = 0;
int input = Int32.Parse(Console.ReadLine());
int min = default;
while (input != 0)
{
Console.ReadLine();
if (i == 0)
{
min = input;
break;
}
if (input < min && i !=0)
{
input = Convert.ToInt32(Console.ReadLine());
min = input;
}
i++;
}
Console.WriteLine(min);
}
First of all you will want to re-read the documentation for for- and while-loops. There are several useful pages out there.. e.g. for / while.
Problem
The reason why your loop breaks is that you initialize i with 0.
int i = 0;
Inside your loop you are using the if-statment to break the loop if the condition "i is 0" is met.
if (i == 0)
{
min = input;
break;
}
The input that the user has to provide each iteration of the loop is ignored by your program as you are never storing this kind of information to any variable.
while (input != 0)
{
Console.ReadLine();
// ...
}
Possible Solution
As a beginner it is helpful to tackle tasks step by step. Try to write down each of this steps to define a simple algorithm. As there are many solutions to this problem one possible way could be:
Declare minimum value + assign max value to it
Use a while loop and loop till a specific condition is matched
Read user-input and try converting it to an integer
Check whether the value is 0 or not
4.1. If the value is 0, go to step 8
4.2. If the value is not 0, go to step 5
Check whether the value is smaller than the current minimum value
5.1. If the value is smaller, go to step 6
5.2. If the value is not smaller, go back to step 3
Set the new minimum
Go back to step 3
Break the loop
End program
A program that handles the above steps could look like:
using System;
namespace FindMinimum
{
public class Program
{
static void Main(string[] args)
{
// Declare minimum value + assign initial value
int minValue = int.MaxValue;
// Loop until something else breaks out
while (true)
{
Console.WriteLine("Please insert any number...");
// Read io and try to parse it to int
bool parseOk = int.TryParse(Console.ReadLine(), out int num);
// If the user did not provide any number, let him retry
if (!parseOk)
{
Console.WriteLine("Incorrect input. Please insert numbers only.");
continue;
}
// If the user typed in a valid number and that number is zero, break out of the loop
if (parseOk && num == 0)
{
break;
}
// If the user typed in a valid number and that number is smaller than the minimum-value, set the new minimum
if (parseOk && num < minValue)
{
minValue = num;
}
}
// Print the result to the console
Console.WriteLine($"Minimum value: {minValue}.");
// Keep console open
Console.ReadLine();
}
}
}
Try This:
int input;
Console.Write("Enter number:");
input = Int32.Parse(Console.ReadLine());
int min = input;
while(true)
{
if (input == 0)
break;
if (min > input)
min = input;
Console.Write("Enter number:");
input = Int32.Parse(Console.ReadLine());
}
Console.WriteLine(min);
Console.ReadKey();
I hope it helps.

C# enter mathematical problem and solve it when user enter "="

I have some test. I need to do and I just can't understand how to do it.
We are asked to make a program that will take the user input (numbers and operators) and will end to take inputs if the user enters "=", then it will solve it.
Example:
user input - 10+10+10+10= (will stop cuz he enterd = and calculate)
will be like that 10+10+10+10=40
int sum;
int num;
char x;
string op;
Console.WriteLine("lets start sum some numbers!");
Console.WriteLine("enter number and than + press = to end and sum all the numbers");
do
{
while (!Console.KeyAvailable)
{
op = Console.ReadLine();
}
} while (Console.ReadKey(true).Key != ConsoleKey.OemPlus);
So this is what I thought to start with but I'm not sure if its the right way.
I managed to find the key available so I think that will check whether or not the user pressed the = key.
It needs to check for every char the user write but the all input in my opinion need to be string.
Anywhay thanks for helpers.
You will need something like this:
string s = "";
while(true)
{
char c = Console.ReadKey().KeyChar;
if(c == '=')
break;
s += c;
}
// here comes the part where you parse and evaluate the formula in s and print the result
try this concept
char x = Console.ReadKey().KeyChar;
if(x != '='){
sum = sum + num;
}else{
Console.WriteLine(sum);
}

How to fix while loop stopping + unhandled exception error

While loops runs through the if statement once and stops.
I am new to c#, so excuse me if I am overlooking something seemingly obvious. I am currently writing a program that visualizes the Collatz conjecture through console entries. The program begins by prompting the user to enter a natural number. The program is supposed to run that number through the formulae of the conjecture until it eventually reaches a value of 1. However, when I type in the number in console, the program runs it through one formula and crashes. It seems that is has a problem with the Double.Parse line. I already tried using the convert method and tried defining "num" as a decimal instead of a double.
{
Console.WriteLine("Enter a natural number:");
Double num = Convert.ToDouble(Console.ReadLine());
while (num != 1)
{
{
if (num % 2 == 0)
{
Console.WriteLine(num / 2);
num = Double.Parse(Console.ReadLine());
}
else
{
Console.WriteLine(num * 3 + 1);
num = Double.Parse(Console.ReadLine());
}
}
Console.ReadLine();
}
}
}
}
To be honest, I'm not positive what you're trying to achieve from the description (i.e., I have not idea what a Collatz conjecture visualization formula is), but I think I figured out what your issue is.
I think you're a little confused about Console.ReadLine(). This method pauses and waits for user input. As a result, during your first loop through the while statement, your program will pause and wait for user input. I think what you're trying to do is take the result of the formula in either the "if" or "else" section and capture that as the new value of "num."
Here is my best guess at what you're trying to achieve:
static void Main(string[] args)
{
Console.WriteLine("Enter a natural number:");
Double num = Convert.ToDouble(Console.ReadLine());
while (num != 1)
{
if (num % 2 == 0)
{
num /= 2;
Console.WriteLine(num);
}
else
{
num = num * 3 + 1;
Console.WriteLine(num);
}
}
Console.WriteLine(num);
Console.ReadLine();
}
Also, it looks like you might have an extra set of brackets within your while statement. It doesn't seem like that would compile as-is, so perhaps it is just the way in which you copied it into your question.

Do while loop is moving to the next step without meeting conditions

I have just started to learn C# this week and am trying to run a simple code that prompts the user to enter a number if they enter text, or prompts them to enter a positive number if they enter a negative one (so a boolean operation for the text, and an if statement for the negative). If they enter a valid (positive) number the program continues on with the rest of the steps.
However with this code, if the user inputs a negative, then a text, then another negative number and so forth it seems to break the loop and continue on with the next operations.
The code is part of a bigger program so I have scaled it down and pulled out only the most critical parts for it to run. Is anyone able to spot what I have missed here?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IncomeTaxCalculator
{
class IncomeTax
{
public static void Main()
{
double income;
income = income_input();
show_output(income);
}
public static double income_input()
{
double income; string income_string; bool bad_value = true;
do
{
Console.Write("What is your total income: ");
income_string = Console.ReadLine();
if (double.TryParse(income_string, out income))
{
bad_value = false;
}
else
{
Console.WriteLine("Enter your income as a whole-dollar numeric figure.");
}
if (income < 0)
{
Console.WriteLine("Your income cannot be a negative");
}
} while (bad_value || income < 0);
return income;
}
public static void show_output(double income)
{
Console.WriteLine("Your income is " + income);
Console.WriteLine("\n\n Hit Enter to exit.");
Console.ReadLine();
}
}
}
Here's what's happening. When you enter a negative number bad_value will be set to false. Then when you enter a non-numeric value income will be set to 0 by the TryParse. Now your condition of bad_value || income < 0 is false. To fix it you just need to reset bad_value to true at the beginning of each loop.
Alternatively you could as René Vogt suggests set bad_value to true in the else and additionally in the if that checks if it is negative and then you can just do while(bad_value).
do
{
Console.Write("What is your total income: ");
income_string = Console.ReadLine();
if (double.TryParse(income_string, out income))
{
bad_value = false;
}
else
{
Console.WriteLine("Enter your income as a whole-dollar numeric figure.");
bad_value = true;
}
if (income < 0)
{
Console.WriteLine("Your income cannot be a negative");
bad_value = true;
}
} while (bad_value);
I realize this has already been accepted but this can be done in a much simpiler loop. Why not just create an infinite loop and break/return when the values are satisfied. Instead of checking for invalid input search for valid input.
I wont go into detail as to why this is a more acceptable solution, consider the instructions given, if you exepect an invalid input then your instructions are wrong. Instead check for positive results. Read This!!
static double income_input()
{
double income = double.NaN;
while (true)
{
Console.WriteLine("What is your income?:");
if (double.TryParse(Console.ReadLine(), out income) && income > 0)
return income;
Console.WriteLine("Invalid input. Please enter a valid number greater than zero.");
}
}
Really all we have done here is created an infinite-loop with the while(true). So now the loop can never end unless we explicitly tell it to.
Next you can simply parse the result and assure the conditions that double.TryParse succeeds and income > 0. Note the return simply exits the loop.
Now this compiles (note there is no return at the end) as the compiler understands that the only exit point is through the return statement. Example Post
If you wanted to go for the shortest code possible could use some C# 7 syntax for inline variables.
static double income_input()
{
while (true)
{
Console.WriteLine("What is your income?:");
if (double.TryParse(Console.ReadLine(), out double income) && income > 0)
return income;
Console.WriteLine("Invalid input. Please enter a valid number greater than zero.");
}
}
Happy Coding!.
Change your code to be something like this:
double income;
string income_string;
do
{
Console.Write("What is your total income: ");
income_string = Console.ReadLine();
} while (!double.TryParse(income_string, out income) || income < 0);
//rest of your code here, in another method that takes the valid income
You should split the method that procures income from the one that has (business ) logic in it.

How to take user input in the same line?

I'm bigener in C# programming
So, I was just wondering about how to take user input in the same line?
this is my code and also I want to print the output in the same line
using System;
namespace Wa2
{
class BodyMassCalculation
{
public static void Main (string[] args)
{
Console.WriteLine ("BMI Calculator\n");
double weight;
Console.WriteLine ("Enter your weight in kilograms: ");
weight = Convert.ToInt16(Console.ReadLine());
double height;
Console.WriteLine ("Enter your height in centimetres: ");
height = Convert.ToInt16(Console.ReadLine());
double meter;
meter = height / 100;
Double BMI;
BMI = (weight) / (meter*meter);
Console.WriteLine ("Your BMI is " , BMI);
Console.WriteLine(BMI.ToString("00.00"));
}
}
}
Try this:
Console.Write("Enter your input here: ");
string userinput = Console.ReadLine();
Just change Console.WriteLine to Console.Write.
Use Console.Write() instead of Console.WriteLine().
I think that's what you mean anyway, the question isn't very clear.
I think you're asking if it's possible to read both height and weight at the same time:
// C equivalent
printf ("Enter height (cm) and weight (kg): ");
scanf ("%d %d\n", &h, &w);
Yes, there are several alternatives.
Arguably the easiest is use Console.ReadLine() (like you're doing) and parse the string.
You can also try multiple "Console.Read()" (one for each argument).

Categories

Resources