static void Main(string[] args)
{
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if( number >= 1000)
{
while (number <= output)
{
switch (conversion)
{
case true:
Console.Write(number + " ");
number += 2;
break;
case false:
Console.WriteLine("ERROR INVALID INPUT!");
break;
}
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
}
string choice = Console.ReadLine();
do // Here is the beginning of the do code
{
Console.WriteLine("Do you want to continue - Yes or No");
if(choice.ToUpper() != "NO" && choice.ToUpper() != "NO");
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
}while(choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
}
}
}
This is a very simple application and is unfinished but what it does is you put in a number below or equal to 1000 and it counts up to it evenly. My only problem is with the do statement at the end of the code. Its unfinished but from what I've researched that do statement is completed what happens is if the user does not input yes or no it will show them that error and then ask again "do you want to go again" However because of this do statement I put in any number like 10 and it gives me the error saying its over 1000 and then goes on an infinite loop of saying "ERROR INVALID INPUT: ONLY INPUT YES OR NO!" How can I fix this?
Your if statement tests for NOT EQUAL to "no" twice, I assume you mean to check for not equal to "YES" and not equal to "NO"
Your infinite loop is because the condition checks the content of choice, but you never change the value of the variable within the do loop - only in the Console.ReadLine() immediately before the loop starts.
You should start the do loop before the code you want to be repeated. For instance, if your intent is that if the user types yes that the entire process repeats, you may be best served by creating a void function, say static void CountNumbers() { ... } that has all the code doing your input on how high to count, error handling, etc. Then you can use your do loop to easily repeat as much as the user wants, like this:
string choice = null;
do
{
CountNumbers();
// Your code here to ask if user wants to continue and readline to get the new choice
} while ( /* Existing condition */);
You have several issues in the code:
First, your condition checks that number is GREATER than or equal to 1000. Since you're entering 10, which is not >= 1000, then you get to the else statement. So you need to change your condition to:
if(number <= 1000)
Next, your condition in the do loop checks the same condition twice... you don't allow the user to enter "yes". You should modifiy the condition to include a check for "yes". Also, you need to remove the semi-colon from the end of that same if statement:
do
{
Console.WriteLine("Do you want to continue - Yes or No");
choice = Console.ReadLine();
if(choice.ToUpper() != "NO" && choice.ToUpper() != "NO");
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
} while(choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
One thing you also might consider is adding a method to get an integer from the user, since it is handy to wrap it in some validation:
public static int GetIntFromUser(string prompt,
string errorMessage = "Invalid entry. Please try again.")
{
int value;
while (true)
{
if (prompt != null) Console.Write(prompt);
if (int.TryParse(Console.ReadLine(), out value)) break;
if (errorMessage != null) Console.WriteLine(errorMessage);
}
return value;
}
Then, you can call this method when you need to get an int from the user. Here's a sample of how it could be used:
private static void GenericTester()
{
// This will flag that the user wants to quit
bool quit = false;
while(!quit)
{
// Get input from user
int userInput = GetIntFromUser("Please input a number to be counted: ");
int number = 0;
// Write out the numbers
if (userInput <= 1000)
{
while (number <= userInput)
{
Console.Write(number + " ");
number += 2;
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW " +
"OR AT 1000 TO PREVENT OVERFLOW!");
}
// See if they want to continue
while (true)
{
// Get user input
Console.Write("Do you want to continue - Yes or No: ");
string choice = Console.ReadLine();
// If they said 'No', set flag to quit and break out of this loop
if (choice.Equals("No", StringComparison.OrdinalIgnoreCase))
{
quit = true;
break;
}
// If they said 'Yes', just break out of this loop
if (choice.Equals("Yes", StringComparison.OrdinalIgnoreCase)) break;
// Otherwise, display an error message and let the loop continue
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
}
}
Related
I've been trying to find a way to do this but not had much luck so far.
Basically what I'm trying to do is limit the entries from the user so they can only enter 1 letter and 1 number using the Console.Readkey. So, for example, A1, E5, J9 etc. I want to avoid them entering like 55 or EE as this causes an error in my code. Is there an easy way to achieve this?
You need to write your own logic like you will check on every input value contains at least 1 number and 1 letter is true else false:
string value = Console.ReadLine();
//you can also check value.length and redirect if length greater than 2
if (value.Length > 2)
{
Console.WriteLine("Please enter correct value");
return;
}
if (value.Contains("Your Number"))
{
if (value.Contains("Your Letter"))
{
//your code goes here
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
}
else
{
Console.WriteLine("Please Enter Correct Value");
}
This uses a GetChar method which requires that you pass a function to check whether the input is a character or a number. It won't allow you so proceed until a valid entry has been made.
using System;
class Program {
public static void Main (string[] args) {
string value = string.Empty;
// Get a character, using char.IsLetter as the checking function...
GetChar(ref value, char.IsLetter);
// Get a number, using char.isNumber as the checking function...
GetChar(ref value, char.IsNumber);
Console.WriteLine($"\nValue: {value.ToUpper()}");
}
// Get a character and append it to the referenced string.
// check requires that you pass a function reference for the required check.
public static void GetChar(ref string value, Func<char, bool> check) {
// Loop until the check passes.
while(true) {
char key = Console.ReadKey(true).KeyChar;
// If check passes...
if(check(key)) {
// Append the value
value += key.ToString().ToUpper();
// Print it...
Console.Write(key.ToString().ToUpper());
// Break out of the loop.
break;
}
}
}
}
I'm trying to make a program that takes a number and print it on screen but if the user press enter the code ask the user to enter the number again but instead it shows me a exception
Enter_No:
Console.WriteLine("enter number");
int? n = Convert.ToInt32(Console.ReadLine());
if (n == (int?)null)
{
goto Enter_No;
}
else
{
Console.WriteLine(n);
}
Use int.TryParse:
int? num = null;
while(!num.HasValue)
{
Console.WriteLine("Please enter an integer:");
num = int.TryParse(Console.ReadLine(), out int i) ? i : new int?();
}
Console.WriteLine("Entered integer: " + num.Value);
Tim's solution is wonderfully compact. Here's why your attempt failed.
From MSDN, Convert.ToInt32() throws a FormatException if:
value does not consist of an optional sign followed by a sequence of digits (0 through 9).
The preferred approach is int.TryParse(), as it returns false if it's unable to parse the integer rather than throwing an exception.
While the goto keyword is supported in C#, there are few or no situations (depending on who you ask) where it's the best option for flow control. Tim's while loop is an excellent approach.
First, don't use Go To:
Second: Inspect your data and use tryparse:
bool success = false;
do
{
Console.WriteLine("enter number");
var n = Console.ReadLine();
if (n == null)
{
// goto Enter_No;
}
else
{
int typedNum;
success = int.TryParse(n, out typedNum);
Console.WriteLine(typedNum);
}
} while (!success);
This question already has answers here:
Parse v. TryParse
(8 answers)
Closed 5 years ago.
I'm trying to handle an exception to avoid my program crash if double.Parse(string) tries parsing invalid values (such as strings instead of numbers). Here's what I've got:
do
{
//asking customer the amount of shirts he would like to buy any shirts they want.
numbershirtString = Console.ReadLine(); // customer types in amount of shirts they want.
numbershirts = double.Parse(numbershirtString);
keepLooping = true;
if (numbershirts < 10)
{
Console.WriteLine("You would be buying " + numbershirts + " shirts");
keepLooping = false;
}
if (numbershirts > 10)
{
Console.WriteLine("You cannot order more than 10 shirts. Please try again.");
keepLooping = true;
}
} while (keepLooping);
I would appreciate your help. Thank you in advance!
Use double.TryParse() instead. It returns true of false depending on the outcome:
double val;
bool success = double.TryParse("red", out val);
if(success)
{
// val contains a parsed value
}
else
{
// could not parse
}
To handle an exception, in C# like similar in other languages, you can use the try..catch block.
Look at the simplest syntax:
try
{
//Try to run some code.
}
catch
{
//Do something if anything excepted.
}
If you're interested to retrieve which exception breaked the code:
try
{
//Try to run some code.
}
catch (Exception ex)
{
//Do something ex was thrown.
}
If you change the type of ex to something inheriting the base class Exception you'll handle only all the exception of that type:
try
{
//Try to run some code.
}
catch (StackOverflowException ex)
{
//Do something ex was thrown because you overflowed the stack.
}
But instead of talking about try..catch block which you can find out more about on Google, I suggest you to use the method double.TryParse(string, out double).
Its syntax is a little bit different than double.Parse, but effectively it does the same in a different way.
It returns true if your input is valid, else it returns false, whereas in the first parameter you have just to pass your string input and in the second one is required an output reference to the result variable:
double x = 0;
string number = "125.3";
if (double.TryParse(number, out x))
Console.WriteLine("Your number is " + x.ToString());
else
Console.WriteLine("Your input isn't valid");
Maybe this is a little advanced for you, but if you are feeling in a clever mood, you can define a class that handles the parsing of user input. That way you can keep that logic separated from your main program (see separation of concerns).
public class UserEntry
{
private readonly string _originalValue;
public UserEntry(string input)
{
_originalValue = input;
}
public bool IsInt
{
get
{
return int.TryParse(_originalValue, out var dummy);
}
}
public int ToInt()
{
return ToInt(default(int));
}
public int ToInt(int defaultValue)
{
int result;
bool ok = int.TryParse(_originalValue, out result);
return ok ? result : defaultValue;
}
public override string ToString()
{
return _originalValue;
}
static public implicit operator UserEntry(string input)
{
return new UserEntry(input);
}
static public implicit operator Int32(UserEntry input)
{
return input.ToInt();
}
}
If we use implicit conversion operators it makes things very simple. For example, all of these are now legal:
UserEntry entry = Console.ReadLine();
if (!entry.IsInt) continue;
if (entry < 10) return entry;
If we apply this to your example, it shortens your code a bit, and arguably makes it a bit clearer as well.
public class Program
{
private const int MaximumOrder = 10;
public static void Main()
{
var n = AskForNumberOfShirts();
Console.WriteLine("OK, I'll order {0} shirts.", n);
}
public static int AskForNumberOfShirts()
{
while (true)
{
Console.WriteLine("Enter the number of shirts to order:");
UserEntry entry = Console.ReadLine();
if (!entry.IsInt)
{
Console.WriteLine("You entered an invalid number.");
continue;
}
if (entry > MaximumOrder)
{
Console.WriteLine("{0} is too many! Please enter {1} or fewer.", entry, MaximumOrder);
continue;
}
return entry;
}
}
}
Notes:
I doubt you can order half a shirt, so I am using an int instead of a double to store the number of shirts.
I refactored the logic branches to use opportunistic return, a.ka. Guard Pattern. See this article for why I do this.
I extracted the constant value 10 to its own symbol, MaximumOrder. This should get you a couple points on the assignment.
Output:
Enter the number of shirts to order:
22
22 is too many! Please enter 10 or fewer.
Enter the number of shirts to order:
sdlfkj
You entered an invalid number.
Enter the number of shirts to order:
9
OK, I'll order 9 shirts.
Working example on DotNetFiddle
I can't figure out how to check whether the input is a specific letter. I know how to check if it's a specific int/double but when it's a string I don't know what to do.
Any help would be greatly appreciated. I'm just trying to make a basic 3 question quiz that checks whether the user answers with the correct letter (a, b or c) and then adds that to the current score.
class Program
{
static void Main()
{
var a1 = "a";
var a2 = "b";
var a3 = "c";
var qa = 0;
while (qa != 3)
{
if (qa == 0)
{
Console.Write("What is the answer to question 1? ");
var entry1 = Console.Read();
if()
{
}
}
else if (qa == 1)
{
Console.Write("What is the answer to question 2? ");
Console.ReadLine();
}
else if (qa == 2)
{
Console.Write("What is the answer to question 3? ");
Console.ReadLine();
}
}
}
}
For example operator == can't be applied to strings
this is not true. It can be applied:
if(entry.ToString() == a1)
The documentation for the == operator tells us:
For the string type, == compares the values of the strings
another possibility would be to use the String.Equals method
if(entry.ToString().Equals(a1))
EDIT:
Looking closer at your code I realized that you are using Console.Read
which
Reads the next character from the standard input stream.
That means that it returns a char (and only 1).
I guess you want the entire line that the user types in. So you should use ReadLine instead. It returns a string and allows you for a direct comparison
string entry1 = Console.ReadLine();
if(entry == a1)
when you use var for the declaration of types the compiler infers the type and the error becomes obvious at a later stage. you cannot use the == operator on string and char . Read() returns a char so that's why you were not able to compare it in the first place
Note that in "Question 1" you wrote Console.Read(), (not Console.ReadLine()) which returns a char, not a string. So "==" cannot be applied to entry1 and a1 since entry1 will be a char while a1 is a string.
If you compare compatible variables, everything should be fine
string input1;
var input2 = "";
var input3 = 0;
// assign some input values, then compare
// strings
if (input1 == "a") // ok
{ }
if (input2 == "a") // ok
{ }
if (input3 == "a") // not ok, comparing int to string
{ }
// numbers
if (input1 == 1) // not ok, comparing string to int
{ }
if (input3 == 1) // ok
{ }
If you want to, you could try matching the ASCII value of the character by using Console.Read();. This would eliminate the need to press enter. If you were trying to match to uppercase A:
int input = Console.Read();
if (input == (int)char.GetNumericValue(A))
{
Console.WriteLine("True");
Console.Read();
}
else
{
Console.WriteLine("False");
Console.Read();
}
i'm having trouble creating a loop that will request user input and if the input is not "Y" or "N" to re-prompt the user to input over and over until they give the correct input.
while (quitOrContinue != "Y"|"N")//cant use "Y"/"N" in the same line, how do I phrase this line?
Console.Write("\nWould you like to process another set of bowling scores?");
Console.WriteLine("\nPress 'Y' to process another set or 'N' to exit the program");
Console.Clear();// this needs to happen if the input to run again is "Y"
Well, for starters, you're not actually taking any input at all from the user. You can use Console.WriteLine to output whatever sort of instructions you want from the user, but you have to actually capture them somehow.
To get input, you'd have to use Console.Read(), and you'd have to use conditional blocks to check their input. You should wrap your code in a while loop that references a sentinel value:
bool userIsDone = false;
Console.Write("\nWould you like to process...");
while (!userIsDone)
{
string userInput = Console.ReadLine();
// ...
if (userInput == "Y")
{
// process another set here
Console.WriteLine("\nWould you like to process...");
}
else if (userInput == "N")
{
// exit your program
}
else
{
Console.WriteLine("That input is invalid.");
}
}
Also, about the code you have above - you should wrap the elements inside loops in { }, and the | is the bitwise OR, not logical or. Logical or (which I'm 99% you want in this situation) is ||, and logical and is &&.
Why not use a loop ?
string input = null;
while((input = Console.ReadLine()) != "Y" || input != "N")
{
Console.WriteLine("Invalid value, please try again:");
}
Here the expression (input = Console.ReadLine()) != "Y" || input != "N" will be evaluated before and each time after the loop runs. It basically reads a line from the input stream and assign it to input variable then checks if it's not Y or N it executes the loop body and evaluates the expression again and ask for input until the condition satisfies.You can use Console.Read method to read one charachter but it returns int so you need to cast it to char.