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

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.

Related

How to multiply correctly two numbers in a method?

{
Console.ForegroundColor= ConsoleColor.Yellow;
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.Clear();
Console.WriteLine("Please enter your name and I will tell you how many letters your name has!");
string name = Console.ReadLine();
Count(name);
Console.WriteLine("Now tell me two numbers and I will multiply them!");
Console.Read();
try
{
Multiply();
}
catch (FormatException)
{
Console.WriteLine("You must enter a number!");
}
}
public static void Count(string name)
{
Console.WriteLine("Your name has {0} letters!", name.Length);
}
public static void Multiply()
{
string firstNum = Console.ReadLine();
string secondNum = Console.ReadLine();
int num = Int32.Parse(firstNum);
int num1 = Int32.Parse(secondNum);
int result = num * num1;
Console.WriteLine("The result is {0}", result);
}
Im a beginner and Im learning about methods so I made this simple code where the user should enter two numbers and I should multiply them, the problem is, whenever I enter two random numbers, I am getting some completely different numbers back no matter if i want to add them, multiply them or something third.
I cannot figure out why the "num1 * num2;" is not giving me a correct number. E.G. 54*19 should give me 1026, but instead its giving me -15.
you need to comment on the Console.Read(); line. this is the main cause.
I have run your code by commenting on the above line and it works as expected for me
Also, you need to handle the scenarios when the user can enter a non-integer input, so you could use int.TryParse for the same.
Also, try to handle the scenario where the integer value is very large and the multiplication of two numbers exceeds the integer max value.

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.

User Input Validation

I am creating a simple income tax calculator and would like too add some user input validations. Currently I am experimenting with a TryParse method. I would like my program to check each input for the specific input types and if an invalid input is entered, the program will first notify the user then ask them to try again.
My current attempt successfully detects whether or not the input types are correct, but I am unsure on how I can redirect the user to retry. Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IncomeTaxCalculator
{
class IncomeTaxV2
{
public static void Main()
{
// Define variables
const double incomeTax = 0.02, deduction = 10000; // Constant values - These never change
int children; // Amount of children
double Taxdue, totalIncomeTax; // Decimal valued variables
// Ask total income
Console.Write("What is your total income: ");
bool succeed = double.TryParse(Console.ReadLine(), out totalIncomeTax);
// Ask amount of children
Console.Write("How many children do you have: ");
bool succeeded = int.TryParse(Console.ReadLine(), out children);
// If statement to check input validation.
if (succeed && succeeded)
{
// User input validation
// Calculate Deductions
int childTax = children * 2000; // total amount for each child
double total_deductions = (double)deduction + childTax; // total deductions = 10k + childtax
// Calculate User input tax takeaway (-) the total amount of deductions (Equation above)
double taxDueCalc = totalIncomeTax - total_deductions;
// Find 2% of the Result for the amount of Tax due
Taxdue = taxDueCalc * incomeTax;
// Print result
Console.Write("You owe a total of $" + Taxdue + " tax.");
} else
{
// Notify user of error
Console.Write("You must enter a valid number.");
// Redirect too first set of TryParse statements
}
// End program
Console.WriteLine("\n\n Hit Enter to exit.");
Console.ReadLine();
}
}
}
Redirect must go into else statement. After researching potential methods it seems I might have too learn too use functions and pass information through parameters.
An easy approach is to use a loop, and signal the end when user entry has completed:
bool entryCompleted = false;
while (!entryCompleted)
{
if (succeed && succeeded)
{
// ..
entryCompleted = true;
}
}
I will use the recursive function for this question.
public static void Main()
{
incomeTax();
// End program
Console.WriteLine("\n\n Hit Enter to exit.");
Console.ReadLine();
}
public void incomeTax()
{
// Define variables
const double incomeTax = 0.02, deduction = 10000; // Constant values - These never change
int children; // Amount of children
double Taxdue, totalIncomeTax; // Decimal valued variables
// Ask total income
Console.Write("What is your total income: ");
bool succeed = double.TryParse(Console.ReadLine(), out totalIncomeTax);
// Ask amount of children
Console.Write("How many children do you have: ");
bool succeeded = int.TryParse(Console.ReadLine(), out children);
// If statement to check input validation.
if (succeed && succeeded)
{
// User input validation
// Calculate Deductions
int childTax = children * 2000; // total amount for each child
double total_deductions = (double)deduction + childTax; // total deductions = 10k + childtax
// Calculate User input tax takeaway (-) the total amount of deductions (Equation above)
double taxDueCalc = totalIncomeTax - total_deductions;
// Find 2% of the Result for the amount of Tax due
Taxdue = taxDueCalc * incomeTax;
// Print result
Console.Write("You owe a total of $" + Taxdue + " tax.");
} else {
// Notify user of error
Console.Write("You must enter a valid number.");
// Redirect too first set of TryParse statements
incomeTax();
}
}
When the input number is invalid, it will call back the same function. This happens until the program enters if statement.

How to block the user from typing text

I'm recreating the game Hammurabi (just an assignment for my uni) and I want somehow my code to check if the user is typing text so it gets in a while loop to prompt him to type text. I know how to make the user type the numbers I want him to but I don't know how to fix it if he types something like "a" then my program will bug.
Here is an example of what I'm talking about:
while (acresToBuy < 0)
{
Console.WriteLine("Please type a positive number or 0");
acresToBuy = int.Parse(Console.ReadLine());
}
int cost = trade * acresToBuy;
while (cost > bushels)
{
Console.WriteLine("We have but " + bushels + " bushels of grain, not " + cost);
acresToBuy = int.Parse(Console.ReadLine());
cost = trade * acresToBuy;
}
You can use Int.TryParse for this. For example:
while (acresToBuy < 0)
{
Console.WriteLine("Please type a positive number or 0");
acresToBuy = int.TryParse(Console.ReadLine(), out acresToBuy) ? acresToBuy : -1;
}
If Int.TryParse fails, then the method will return false, in which then we assign -1 to acresToBuy, otherwise, if it succeeds, we simply assign it back to itself.
You shouldn't use int.Parse (or other types' equivalents) unless you can absolutely guarantee that the input will be parsable, and that's something you cannot do where user input is involved. Instead, you should use int.TryParse:
do
{
Console.WriteLine("Please type a positive number or 0");
int input;
if (int.TryParse(Console.ReadLine(), out input)
&& input >= 0) // You can validate the input at the same time
{
acresToBuy = input;
}
else
{
Console.WriteLine("That was not the correct input. Please try again.");
acresToBuy = -1;
}
} while (acresToBuy < 0);
Edit: The while loop will always check it's condition first before executing, so keep in mind that your code will only run if acresToBuy has an initial value of something less than 0 (i.e. -1). To prevent from having to constantly check this against pre-existing conditions, you should instead use a do-while loop, which will always run at least once.

List of numbers in C# and getting min and max value without retaining variables stored in previous loop

So I have this thing that displays minimum and maximum numbers from a series of numbers inputed, please note I am just a beginner and haven't learned arrays or sorting yet:
namespace ConsoleApplication12
{
class Program
{
static void Main(string[] args)
{
double number, maxValue= Double.MinValue , minValue= Double.MaxValue;
string goOn = "Y";
Console.WriteLine("Please enter a series of numbers, when you wish to stop entering numbers please enter -99.");
Console.WriteLine("The smallest and largest values will then be displayed.");
Console.WriteLine("Remember not to enter -99 unless you want the series to end.");
do
{
while (!double.TryParse(Console.ReadLine(), out number))
Console.WriteLine("Please enter whole numbers only");
while (number != -99)
{
process(ref minValue, ref maxValue, number);
while (!double.TryParse(Console.ReadLine(), out number))
Console.WriteLine("Please enter whole numbers only");
}
Console.WriteLine("The smallest value is {0} and the largest value is {1}.", minValue, maxValue);
Console.WriteLine("Do you want to enter another series of numbers?");
Console.WriteLine("If so enter y, if you want to end press any other key");
goOn = Console.ReadLine();
if (goOn.ToUpper() == "Y")
{
Console.WriteLine("Please enter your set of numbers.");
Console.WriteLine("Remember not to enter -99 unless you want the series to end.");
}
} while (goOn.ToUpper() == "Y");
}
static void process(ref double minValue, ref double maxValue, double number)
{
if (number > maxValue)
{
maxValue = number;
}
if (number < minValue)
{
minValue = number;
}
}
}
}
But when I enter a series of numbers, and then stop, and then make another list of numbers, it retains the minimum and maximum from the previous list as shown:
Also I am sorta doing my own version of someone else's program like this but can't figure out how he is able to do it with setting maxValue = 0 and minValue = 0. He does use Int64 instead of double though and used three modules instead of 1 and another if statement for if minValue and maxValue are 0.
If you need to search for min and max in new sequence, just clear out the previously saved values:
if (goOn.ToUpper() == "Y")
{
maxValue= Double.MinValue;
minValue= Double.MaxValue;
Console.WriteLine("Please enter your set of numbers.");
Console.WriteLine("Remember not to enter -99 unless you want the series to end.");
}
You're never resetting the values of maxValue and minValue at the end of each iteration of the do-while loop. Since you're not doing that your program is holding onto the previous numbers that were used.
You should reset them both to whatever you set them to at the beginning of your program at the last line before the end of the do-while loop.

Categories

Resources