Only allowing yes or no as an answer - c#

I am a complete newbie and i am stuck on a small problem
I want the user to only be able to have yes or no as an answer.
This is what I came up with
static public bool askBool(string question)
{
try
{
Console.Write(question);
return Console.ReadLine() == "y";
}
catch (Exception)
{
throw new FormatException("Only y or n Allowed");
}
}
The problem is entering any other letter then 'y' will result in false, how can I best solve this ?
Thank you in advance.
EDIT (from comment question)
try
{
Console.Write(question);
return int.Parse(Console.ReadLine());
}
catch (Exception)
{
throw new FormatException("Please Enter a Number");
}

I doubt if you want an exception to be thrown - there's nothing exceptional if the user puts OK instead of yes; I suggest to keep asking until "yes" or "no" are read:
public static AskBool(string question) {
while (true) {
// If we have a question to ask (the question is not empty one)...
if (!string.IsNotNullOrWhiteSpace(question))
Console.WriteLine(question); // ... ask it
// Trim: let be nice and trim out leading and trailing white spaces
string input = Console.ReadLine().Trim();
// Let's be nice and accept "yes", "YES", "Y" etc.
if (string.Equals(input, "y", StringComparison.OrdinalIgnoreCase) ||
string.Equals(input, "yes", StringComparison.OrdinalIgnoreCase))
return true;
else if (string.Equals(input, "n", StringComparison.OrdinalIgnoreCase) ||
string.Equals(input, "no", StringComparison.OrdinalIgnoreCase))
return false;
// In case of wrong user input, let's give a hint to the user
Console.WriteLine("Please, answer yes or no (y/n)");
}
}

Here the method will only return true or false if user has entered true or false.If user enters any word the loop will just continue to ask him for input until he enters y or n
you can give it a try by doing following changes
static public bool askBool(string question)
{
bool boolToReturn = false;
Console.Write(question);
while (true)
{
string ans = Console.ReadLine();
if (ans != null && ans == "y")
{
boolToReturn = true;
break;
}
else if ( ans != null && ans == "n")
{
boolToReturn = false;
break;
}
else
{
Console.Write("Only y or n Allowed");
}
}
return boolToReturn;
}`
Answer to second question:-
`
public static int askInt(string question)
{
Int intToReturn = false;
Console.Write(question);
while (true)
{
string ans = Console.ReadLine();
if (int.TryParse(and,out intToreturn))
break;
else
Console.Write("Only number Allowed");
}
return intToReturn;
}`

A bit more simplified version of Dmitry's answer with switch (what I normally do for this kind of scenarios):
static public bool askBool(string question)
{
while(true)
{
Console.Clear();
Console.Write(question);
var input = Console.ReadLine().Trim().ToLowerInvariant();
switch (input)
{
case "y":
case "yes": return true;
case "n":
case "no": return false;
}
}
}
Also I'd consider changing .ReadLine() to .ReadKey() because what we really need here is just 'y' or 'n'... One key is enough.
We use Exceptions mostly for scenarios when unexpected value will lead to some error. We don't throw an exception when we expect user to enter rubbish values and handle them.

You want to throw the exception, not catch it. Example:
static public bool askBool(string question)
{
Console.Write(question);
var input = Console.ReadLine();
if (input == "y")
{
return true;
}
else if(input == "n")
{
return false;
}
else//It's not y or n: throw the exception.
{
throw new FormatException("Only y or n Allowed");
}
}
Of course, you must then capture the 'FormatException' where you call this method.

Something like this?
if (Console.ReadLine() == "y")
{
return true;
}
else if (Console.ReadLine() == "n")
{
return false;
}
else {
throw new Exception("only y and n allowed...");
}

Here another idea:
public static bool ReadUserYesOrNo()
{
bool userSaysYes = true;
Console.Write("Y\b");
bool done = false;
while (!done)
{
ConsoleKeyInfo keyPressed = Console.ReadKey(true); // intercept: true so no characters are printed
switch (keyPressed.Key) {
case ConsoleKey.Y:
Console.Write("Y\b"); // print Y then move cursor back
userSaysYes = true;
break;
case ConsoleKey.N:
Console.Write("N\b"); // print N then move cursor
userSaysYes = false;
break;
case ConsoleKey.Enter:
done = true;
Console.WriteLine();
break;
}
}
return userSaysYes;
}
This will print the default value Y to the console. By pressing Y or N the user can toggle between the two values. The character in the console output will be overwritten. Pressing 'enter' selects the choice and the method returns the result.

Related

If statement problem: ignoring other statements even if its true(?)

Even if the user input matches the string operations, the statement always results to a false which in turn shows the error prompt.
pardon my code if it seems mediocre, I just started to learn programming for not less than a week. I believe my problem is too specific that's why I'm having a hard time finding a solution. Any will be appreciated.
Console.Write("What Operation?: ");
string input = Console.ReadLine();
if (input == "+")
{
op = input;
}
if (input == "-")
{
op = input;
}
if (input == "*")
{
op = input;
}
if (input == "/")
{
op = input;
}
else
{
op = "Enter a valid operation!!!";
Console.WriteLine(op);
Console.ReadLine();
}
if the user writes the correct operation: it should store it to "op" then will be used for the equation.
You can try loop: keep asking when input is not within validInputs:
// Let's organize all valid input as a collection for better
// readability and better maintenance
HashSet<string> validInputs = new HashSet<string>() {
"+", "-", "*", "/",
};
// Keep asking...
while (true) {
// $"...{string.Join(...)}..." let's be nice and let user know
// which operations are supported: "+, -, *, /"
Console.Write($"What Operation? ({string.Join(", ", validInputs)}): ");
// Trim() - let's be nice and tolerate leading / trailing spaces
string input = Console.ReadLine().Trim();
// ... until user provides a valid input (i.e. which is in validInputs)
if (validInputs.Contains(input)) {
op = input;
break;
}
Console.WriteLine("Enter a valid operation!!!");
}
The else block relates to the previous if statement, so you have:
if (input == "/")
{
op = input;
}
else
{
op = "Enter a valid operation!!!";
Console.WriteLine(op);
Console.ReadLine();
}
Which will mean the else block will execute every time the input is not equal to "/".
Instead of using lots of if statements you can use a switch statement:
Console.Write("What Operation?: ");
string input = Console.ReadLine();
string op;
switch (input)
{
case "+":
op = input;
break;
case "-":
op = input;
break;
case "*":
op = input;
break;
case "/":
op = input;
break;
default:
op = "Enter a valid operation!!!";
Console.WriteLine(op);
Console.ReadLine();
break;
}
The else in your case is an else for the if condition above it. So whenever the input is not "/" your else will fire.
To fix that you can change your 2nd to 4th if to "else if".
The 'else' block here is only related to the last 'if' block (input == '/') so any input that is not '/' will go to this else block.
What I believe you wanted to do is to perform the last check when all other checks failed. For that you'd need an 'else if':
if (input == "+")
{
op = input;
} else if (input == "-")
{
op = input;
} else if (input == "*")
{
op = input;
} else if (input == "/")
{
op = input;
}
else
{
op = "Enter a valid operation!!!";
Console.WriteLine(op);
Console.ReadLine();
}
However a better way (more readable) would be to use switch

Add a second command that calls another method?

I'm remaking a text-based adventure game. During the character creation, I'd like for the user, at any time, to type 'skillset' and list all the traits that a specific race has. I've tried for a couple hours and can't seem to figure it out.
This is my character creation class.
public string userCommand_SeachSkill;
SkillSet searchSkill = new SkillSet();
public void Create_Character()
{
// CHOOSE GENDER //
do
{
validate = 0;
Console.Clear();
Console.Write("Are you male or female? (f/m): ");
Sex = Console.ReadLine().ToUpper();
if (Sex == "M" || Sex == "F")
{
validate = 1;
}
else if (Sex != "M" || Sex != "F")
{
Console.WriteLine("You must enter 'm' or 'f'");
}
} while (validate == 0);
And this is my Skill Set Class. Everything in the if/else statements are methods to print the traits of a race to the console. Let me know if there is anything else I can add to better ask my question. Thank you in advance! :)
ClassAttributes classes = new ClassAttributes();
Character character = new Character();
skillset = Console.ReadLine().ToUpper();
do
{
validate = 0;
if (skillset == "HUMAN")
{
classes.SkillSetHuman();
}
else if (skillset == "ORC")
{
classes.SkillSetOrc();
}
else if (skillset == "ELF")
{
classes.SkillSetElf();
}
else if (skillset == "EXIT")
{
validate = 1;
character.Create_Character();
}
} while (validate == 0);
I think you're looking for something like an event. C# Console Applications only seem to have one kind of event, it fires when ctrl+c or ctrl+break happens. You could handle your skillset input/output logic in the function handler
You can read more here:
https://msdn.microsoft.com/library/system.console.cancelkeypress(v=vs.110).aspx
If you really need the word to be typed, you could capture everything that is typed in a special function, instead of using regular Console.ReadLine(). Something like this:
public static string CustomReadLine()
{
ConsoleKeyInfo cki;
string capturedInput = "";
while (true)
{
cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.Enter)
break;
else if (cki.Key == ConsoleKey.Spacebar)
{
capturedInput += " ";
Console.Write(" ");
}
else if (cki.Key == ConsoleKey.Backspace)
{
capturedInput = capturedInput.Remove(capturedInput.Length - 1);
Console.Clear();
Console.Write(capturedInput);
}
else
{
capturedInput += cki.KeyChar;
Console.Write(cki.KeyChar);
}
if (capturedInput.ToUpper().Contains("SKILLSET"))
{
capturedInput = "";
skillsetTyped();
return "";
}
}
return capturedInput;
}
then inside your Create_Character, do
...
do
{
Console.Write("Are you male or female? (f/m): ");
Sex = CustomReadLine();
} while (String.IsNullOrEmpty(sex));
And finally, handle the skillset logic here
protected static void skillsetTyped()
{
Console.Write("\nWrite your skillset capture/display logic here\n");
}
This is just a draft and has some minor bugs, but I believe it's close to what you really want.

Need to validate a set of user input before triggering a method c#

I need to check a set of user Input from my console application before triggering my method and store data into my database.
The program compiles and rund without exceptions. But in case of one wrong Input it still runs through for the other three.
Although, what I really need is to make sure the 4 user's entries are correct before triggering the method and in case just one is wrong the whole program should stop and exit.
using System;
using System.Threading;
namespace BarcodeValidation
{
class Program
{
static void Main(string[] args)
{
ReadBarcode();
}
static void ReadBarcode()
{
var barcodes = GetInput();
foreach (var item in barcodes)
{
// something
CheckUserInput(item);
}
}
static string[] GetInput()
{
Console.WriteLine("Please enter 4 products ID, Barcodes, MPN or EAN code:");
string[] barcode = new string[4];
for (int i = 0; i < barcode.Length; i++)
{
barcode[i] = Console.ReadLine();
}
return barcode;
} // end of method here
static void CheckUserInput(string userInput)
{
int msec = 5000;
try
{
if (!(userInput == "F5121" || userInput == "F3111" || userInput == "F8331" || userInput == "F5321"))
{
Console.WriteLine("Enter a valid MPN codes for your products");
Thread.Sleep(msec);
Environment.Exit(0);
}
else
{
switch (userInput)
{
case "F5121":
Console.WriteLine("barcode 1 is =", userInput);
Thread.Sleep(msec);
break;
case "F3111":
Console.WriteLine("barcode 2 is =", userInput);
Thread.Sleep(msec);
break;
case "F8331":
Console.WriteLine("barcode 3 is =", userInput);
Thread.Sleep(msec);
break;
case "F5321":
Console.WriteLine("barcode 4 is =", userInput);
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Since you have a method that actually tests your user input use it's return value:
static bool CheckUserInput(string userInput) // true : valid | false : invalid
{
int msec = 5000;
try
{
if (!(userInput == "F5121" ||
userInput == "F3111" ||
userInput == "F8331" ||
userInput == "F5321"))
{
Console.WriteLine("Enter a valid MPN codes for your products");
return false;
}
else
{
switch (userInput)
{
case "F5121":
Console.WriteLine("barcode 1 is =", userInput);
Thread.Sleep(msec);
return true;
case "F3111":
Console.WriteLine("barcode 2 is =", userInput);
Thread.Sleep(msec);
return true;
case "F8331":
Console.WriteLine("barcode 3 is =", userInput);
Thread.Sleep(msec);
return true;
case "F5321":
Console.WriteLine("barcode 4 is =", userInput);
return true;
default:
return false;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
ReadBarcodes could look like this:
static void ReadBarcode()
{
var barcodes = GetInput();
bool errorOccured = false;
foreach (var item in barcodes)
{
// something
if(!CheckUserInput(item))
{
errorOccured = true; // keep track of that error
break; //Break for if 1 input is invalid
}
}
//Further execution....
if(errorOccured)
{
return; //Do not continue ...
}
//Do other things you want to do. Your input is valid at this point !
}
or shorter like Default quoted:
static void ReadBarcode()
{
if(!GetInput().All(CheckUserInput))
{
return;
}
//Your stuff goes here. Input is valid at this point
}
One option you could employ is create your own class that derives from System.Exception, and in cases where one of the inputs is found to be invalid, you could throw an instance of your exception class.
You could wrap your code in a try-catch block, and then put the remediation code within the catch block.
You need to break the checking code and the "output" code into different places. You need to check if all the values are valid values. and AFTER you have checked all the values, then do your console.writelines (Which is the part you dont want to happen). At the moment it checks one and executes the code if that one is valid, and then moves on to the next one. CheckUserInput should really ONLY check the users input, it should not do something else you want to restrict based on that methods result. You should have CheckUserInput and a ExecuteBarcodeStuff for example, and only if all CheckUserInputs return true, should you run the new (as yet unimplemented) ExecuteBarcodeStuff
Mixing this approach with other peoples answers that do Linq queries or such to ensure all the results were positive matches will get you the result you desire.

How to Check for valid input c#

i'm trying to make this method like, if you haven't pressed the correct value a message box will show and when you press the messagebox it will return and you have to try to put the rigth values in again and so on. And if the field is null or empty is has to give =0.. If i press ex. e2 it has to pup up with the message box??
have tried this one without the else if.. and the messagebox vil not disappear? please help
public int playerOneDart1Value;
public int calculateDart1()
{
if (player == "t1" || player == "T1" || player == "3")
{
playerOneDart1Value = 3;
}
else if (player == null) or empty??
{
playerOneDart1Value = 0;
}
else
{
MessageBox.Show("not valid input");
return calculateDart1();
}
return playerOneDart1Value;
}
You're calling return calculateDart1(); straight after showing the message box, so the user never has a chance to alter the input, before the check being made again, and showing the message box.
You are calling the function calculateDart1 recursively and so the reason the messagebox won't disappear is that MessageBox.Show("not valid input"); is being called over and over again.
You're calling calculateDart1() right after the MessageBox prompt which results in an endless loop which makes the user unable to provide new input. For your "null or empty" requirement, you can use string.IsNullOrEmpty which returns true if a string is either null or empty.
public int playerOneDart1Value;
public int calculateDart1()
{
if (string.IsNullOrEmpty(player))
{
playerOneDart1Value = 0;
}
else if (player == "t1" || player == "T1" || player == "3")
{
playerOneDart1Value = 3;
}
else
{
MessageBox.Show("not valid input");
//you can use something like a negative value to indicate invalid input
playerOneDart1Value = -1;
}
return playerOneDart1Value;
}

C# prompting for a boolean value

My searches have come up blank, or I am just not understand the results that I am finding. I am trying to prompt the user to input a boolean value, but I want the answer to be yes or no. Let me know if you need to see more code but I have this for the prompt.
public static bool getBoolInputValue(string inputType)
{
bool valid = false;
bool value = true;
string inputString = string.Empty;
do
{
inputString = GetInput(inputType);
if (!(String.IsNullOrEmpty(inputString)))
{
valid = bool.TryParse(inputString, out value);
}
if (!valid)
Console.WriteLine("Invalid " + inputType + " try again!");
} while (!valid);
return value;
}
This is the paramater for my boolean. Maybe this needs to be more specific?
public bool Nitrus
{
set { nitrus = value; }
get { return nitrus; }
}
Thank you for the help. I am fairly new to programming but cannot figure this out. It does prompt successfully, but it does not matter what answer I put into the box, it tells me it is not the right format.
If I understand correctly you want the user to type in "yes" and that will mean you have a True value. If that is correct, skip all the string.IsNullOrEmpty and bool.TryParse stuff and do something more like this.
//make it ToLower so that it will still match if the user inputs "yEs"
inputString = GetInput(inputType);
if (inputString.ToLower() == "yes")
{
value = true;
}
else
{
value = false;
}
//note that the if/else code is the same as directly applying
// the value from the comparison itself:
// value = inputString.ToLower() == "yes";
// this allows the user to type in "yes" or "y":
// value = inputString.ToLower() == "yes" || inputString.ToLower() == "y";
Boolean.TryParse only recognizes "True" and "False". For "Yes" and "No` or "On" and "Off", you need to write your own function.
public static bool getBoolInputValue()
{
bool value;
bool valid;
do
{
Console.WriteLine("Enter yes or no: ");
var inputString = Console.ReadLine();
if (String.IsNullOrEmpty(inputString))
{
continue;
}
if ( string.Equals(inputString, "yes")
{
value = true;
valid = true;
}
else if ( string.Equals(inputString, "no")
{
value = false;
valid = true;
}
} while (!valid);
return value;
}
Your program will only accept 'true' or 'false' as valid boolean values. If you want 'yes' or 'no', then you will need to do a string comparison.
valid = string.Compare(inputString, "yes", true) == 0 || string.Compare(inputString, "no", true) == 0;
...
value = string.Compare(inputString, "yes", true) == 0;

Categories

Resources