C# prompting for a boolean value - c#

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;

Related

C# “String may be null here” but I don't think it can be null

So I wanted to make a sort of “name checker” that’s always had the first letter be capital and the rest lowercase. I got that to work but whenever I got past the name checker and wanted to use the name in future code, it would always say “string may be null here.” I have tried many things like adding a ? But nothing works. I don’t think it can be null but maybe I’m wrong. Here is my code here:
class Program
{
static void Main()
{
string? name, choice;
bool finishnameingcharacter;
finishnamingcharacter = true;
while(finishingnamingcharacter == false)
{
Console.WriteLine("Enter your name");
name = Console.ReadLine();
name = name?.ToLower();
if(name != null)
{
name = char.ToUpper(name[0]) + name.Substring(1);
}
Console.WriteLine("");
Console.WriteLine("Your name is " +name+ ", is that correct?");
Console.WriteLine("");
Console.WriteLine("1: Yes");
Console.WriteLine("2: No");
choice = Console.ReadLine();
if(choice == "1")
{
finishnamingcharacter = 1;
}
if(choice == "2")
{
Console.WriteLine("");
}
else
{
Console.WriteLine("Invalid Claim")
}
}
Console.WriteLine(name);
}
}
The "name" at the bottom is where the error is. If there's any confusion about my question ask me. I tried my best to explain it.
I could not compile your code, so I made some changes
static void Main()
{
var name = string.Empty;
var choice = string.Empty;
do
{
Console.WriteLine("Enter your name");
name = Console.ReadLine();
name = name?.ToLower();
if (name != null && name.Length>1)
name = char.ToUpper(name[0]) + name.Substring(1);
Console.WriteLine("");
Console.WriteLine("Your name is " + name + ", is that correct?");
Console.WriteLine("");
Console.WriteLine("1: Yes");
Console.WriteLine("2: No");
choice = Console.ReadLine();
if (choice == "1") break;
if (choice == "2")Console.WriteLine("");
else Console.WriteLine("Invalid Claim");
} while (true);
Console.WriteLine(name);
}
Why use a nullable string in this software?
You didn't initialize the name at the beginning, if your loop will never run, then the name output line will be NULL. This is what your error points to.
It is better to initialize variables before their first use, as they can be NULL by default (valid for reference types such as classes). For a string, one option would be String.Empty
string name = String.Empty, choice = String.Empty;
These two lines can be combined:
bool finishnameingcharacter;
finishnamingcharacter = true;
// Replaced by
bool finishnameingcharacter = true;
On the next line in the while loop, you check the condition: finishingnamingcharacter == false. The loop checks the condition and only then executes. To execute the loop, you need the condition to be TRUE, but it will not take this value, because earlier you defined the variable finishnamingcharacter = true. true != false. By default you need to define this variable as false
bool finishnameingcharacter = false;
The user can enter an empty string value, so converting it to lowercase immediately doesn't matter, as long as it checks for an empty string. There is a special method for checking if a string is empty: string.IsNullOrEmpty() - it returns true if the string is empty or null.
If the user entered the wrong name, then we need to ask him to enter again, for this, the continue operator is used.
name = Console.ReadLine();
if(string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name))
{
Console.WriteLine("Sorry, your name is empty. Please enter again.")
continue;
}
//So if name is not empty: jOhN
name = name.ToLower(); //john
name = char.ToUpper(name[0]) + name.Substring(1); //John
For boolean values it is better to use reserved words, i.e. instead of finishnamingcharacter = 1 it is better to write finishnamingcharacter = true
Rest of the code looks good. We all took the first steps :)
Full modified code here:
class Program
{
static void Main()
{
string name = String.Empty choice = String.Empty;
bool finishnameingcharacter = false;
while(finishingnamingcharacter == false)
{
Console.WriteLine("Enter your name");
name = Console.ReadLine();
if(string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name))
{
Console.WriteLine("Sorry, your name is empty. Please enter again.")
continue;
}
//So if name is not empty: jOhN
name = name.ToLower(); //john
name = char.ToUpper(name[0]) + name.Substring(1); //John
Console.WriteLine("");
Console.WriteLine("Your name is " +name+ ", is that correct?");
Console.WriteLine("");
Console.WriteLine("1: Yes");
Console.WriteLine("2: No");
choice = Console.ReadLine();
if(choice == "1")
{
finishnamingcharacter = true;
}
else if(choice == "2")
{
Console.WriteLine("");
}
else
{
Console.WriteLine("Invalid Claim")
}
}
Console.WriteLine(name);
}
}
PS There is a special method TextInfo.ToTitleCase() "wAr aNd pEaCe to titlecase: War And Peace" - I advise you to read

Only allowing yes or no as an answer

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.

Is there something wrong with my If Statements?

This function checks if the values in the text boxes are parsable or not. This method is called upon in the method below this.
private bool CheckForInvalidEntries()
{
bool ParseIsSuccessfull; int result; //These 2 variables are for trying to parse the entries in the Stat text boxes
bool ContainsInvalidEntry = false;
if ((ParseIsSuccessfull = int.TryParse(P1STRtextbox.Text, out result)) == false)
{
ContainsInvalidEntry = true;
}
else if ((ParseIsSuccessfull = int.TryParse(P1DEXtextbox.Text, out result)) == false)
{
ContainsInvalidEntry = true;
}
else if ((ParseIsSuccessfull = int.TryParse(P1VIGtextbox.Text, out result)) == false)
{
ContainsInvalidEntry = true;
}
else if ((ParseIsSuccessfull = int.TryParse(P1RMtextbox.Text, out result)) == false)
{
ContainsInvalidEntry = true;
}
else if ((ParseIsSuccessfull = int.TryParse(P1BMtextbox.Text, out result)) == false)
{
ContainsInvalidEntry = true;
}
else ContainsInvalidEntry = false;
return ContainsInvalidEntry;
}
This function is the event where if the process stat points button is clicked
private void p1ProcessPointsBtn_Click(object sender, EventArgs e)
{
bool EntriesAreInvalid = new bool();
EntriesAreInvalid = CheckForInvalidEntries();
if (EntriesAreInvalid == true)
{
P1STRtextbox_TextChanged(sender, e);
P1DEXtextbox_TextChanged(sender, e);
P1VIGtextbox_TextChanged(sender, e);
P1RMtextbox_TextChanged(sender, e);
P1BMtextbox_TextChanged(sender, e);
}
else
{
MessageBox.Show("Success");
}
FUNCTIONALITY: When the user presses the "Process Stat Points" button, the program checks whether the entries in the 5 text boxes are able to be parsed(in the CheckForInvalidEntries method). It then returns a bool value to the EntriesAreInvalid variable(in the p1ProcessPointsBtn_Click method). If the entries are not parsable, do action A, if the entries are parsable, do action B.
PROBLEM: If the numbers are parsable in all the text boxes, I don't get a result. Im only getting results if the text boxes are not parsable. I think it has something to do with the if statements within the "CheckForInvalidEntries" method. What can I do to fix my problem. Your time and effort is greatly appreciated!
TryParse sets Result to zero if the conversion fails. Since you keep calling TryParse you keep resetting Result.
If you only want to check for parsing errors, this ought to work:
ContainsInvalidEntry = false;
ContainsInvalidEntry |= !int.TryParse(P1STRtextbox.Text, out result));
ContainsInvalidEntry |= !int.TryParse(P1DEXtextbox.Text, out result));
ContainsInvalidEntry |= !int.TryParse(P1VIGtextbox.Text, out result));
ContainsInvalidEntry |= !int.TryParse(P1RMtextbox.Text, out result));
ContainsInvalidEntry |= !int.TryParse(P1BMtextbox.Text, out result));
return ContainsInvalidEntry;
Aside: Comparing boolean values to true and false is a bit (Pardon the pun.) strange. if ( ( ParsedOkay == ( false ) ) ) may be valid, but if ( !ParsedOkay ) is more common.
i was too confused by your code. But i think this will help you. If i got you right you wanted to check if all the text in the textboxes is parsable to an int. And if it is so you wanted to print out "succes";
private bool isParsable(TextBox t) //takes a TextBox as paramater and returns true if
{ // its parsable
int i = 4;
if (int.TryParse(t.Text, out i) == true)
return true;
else
return false;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if(isParsable(tbox1) == true && isParsable(tbox2) == true) //if every textbox
{ //is parsable print
tblock1.Text = "succes";
}
else
{
tblock1.Text = "error";
}
}
First of all you don't need to write your if statements like this, it's too messy and unnecessary. Complex code always prone to error,
Instead of this:
if ((ParseIsSuccessfull = int.TryParse(P1STRtextbox.Text, out result)) == false)
You could write:
if(!int.TryParse(P1STRtextbox.Text, out result))
Because TryParse already returning a bool result.If you want check whether it's false just put negation operator (!) beginning of your statement. Also you can write a simple method to check whether your texts are parsable or not:
static bool CheckForParse(params string[] values)
{
int x;
if(values.Lenght > 0)
{
for(int i=0; i<values.Lenght;i++)
{
if(!int.TryParse(values[i], x)) return false;
}
return true;
} else { return false }
return false;
}
And you can call it like this:
bool result = CheckForParse(P1STRtextbox.Text,
P1DEXtextbox.Text,
P1VIGtextbox.Text,
P1RMtextbox.Text,
P1BMtextbox.Text);
if(result)
{
P1STRtextbox_TextChanged(sender, e);
P1DEXtextbox_TextChanged(sender, e);
...
}

Check if an array contains an invalid value and return false?

This is probably very simple but I guess I haven't had enough of coffee yet.
I have an array with four values and I want to check if any of them is invalid and then set a boolean value to false, else to true.
bool validDecoding = false;
foreach (string decodedValue in arrayOfvalues)
{
if (decodedValue.Contains("invalid") || decodedValue.Contains("length") || decodedValue.Contains("bad"))
{
validDecoding = false;
}
else
{
validDecoding = true;
}
}
But if the last does not contain invalid, length or bad then validDecoding is set to true but I want it to be false if one or more values are invalid.
Please help?
Thanks in advance.
Include System.Linq namespace and you can do following:
validDecoding = !arrayOfvalues.Any(
value => value.Contains("invalid") || value.Contains("length") || value.Contains("bad"));
bool validDecoding = false;
foreach (string decodedValue in arrayOfvalues)
{
if (!decodedValue.Contains("invalid") && !decodedValue.Contains("length") && !decodedValue.Contains("bad"))
{
validDecoding = true;
break;
}
}
Set valid to true at first, then set it to false in your loop if it's invalid.
bool validDecoding = true;
foreach (string decodedValue in arrayOfvalues)
{
if (decodedValue.Contains("invalid") || decodedValue.Contains("length") || decodedValue.Contains("bad"))
{
validDecoding = false;
break;
}
}
That way it's never set back to true! (you need more coffee ;-) )
Set your validDecoding to 'true' initially, and only reset to false if it breaks.
bool validDecoding = true;
foreach (string decodedValue in arrayOfvalues)
{
if (decodedValue.Contains("invalid") || decodedValue.Contains("length") || decodedValue.Contains("bad"))
{
validDecoding = false;
}
else
{
//Do Nothing
}
}
I like Andrew's answer. If you don't have Linq available, try this option:
// Note: Name boolean variables like they are a question
bool isValidDecoding = true;
foreach (string decodedValue in arrayOfvalues)
{
isValidDecoding &= !decodedValue.Contains("invalid")
&& !decodedValue.Contains("length")
&& !decodedValue.Contains("bad");
}
I particularly like this option when your tests contain logging, and you want to find all failures before termination.
I'd be wary of decodedValue.Contains("length") though. Maybe it works in your scenario, but it might give false negatives for other cases, and definitely makes your code less clear. You should double check that there isn't a more unique/indicative value that ensures that you have a bad decoding for those cases.

Error when assigning a boolean value

I am getting an error while assigning a value.
My code is:
protected bool ValidateProfile()
{
bool blnFirstName = false;
bool blnLastName = false;
bool blnEMail = false;
//(error on line below: "The left-hand side of an assignment must be a variable, property or indexer")
ValidateProfile() = false;
if txtFName != ""
blnFName = true;
if txtLName != ""
blnLName = true;
if txtEMail != ""
blnEMail = true;
if (blnFName) && (blnLName) && (blnEMail))
ValidateProfile = true;
}
How do I assign a boolean value to ValidateProfile ?
Thanks
You want
return false;
In C#, we don't assign values to the function name in order to return a value.
If you want to set the return value at a different point in time from when you return from the method, then you should do something like this:
bool retVal; // Defaults to false
if (condition)
retVal = true;
if (otherCondition)
retVal = false;
if (thirdCondition)
retVal = true;
return retVal;
You can't assign a value to a function. You need return false;
As others have pointed out, in C# you use return instead of MyFunction = x. In this scenario, you can assign the result of your final check to a boolean and return it:
bool retVal = (blnFName) && (blnLName) && (blnEMail);
return retVal;
Alternatively, you could just skip the assignment altogether:
return (blnFName) && (blnLName) && (blnEMail);
EDIT: I noticed you are using hungarian notation, which implies that txtFName is a TextBox. Keep in mind that C# doesn't have default properties like VB. If it is a TextBox, it will never equal "", because it's not of type System.String. I'm guessing you actually wanting to evaluate txtFName.Text
Change that last line to:
return false;
Although it seems you're always returning false here. Is there an option to return true?
Just a side note besides all the returns...
You may want to change this:
if txtFName != ""
To check if the String.IsEmptyOrNull(txtFName.Text)
Or at least initialize your variables to either null or String.Empty.
Just an FYI though.
You want to return false
Alright, taking the code you posted:
protected bool ValidateProfile()
{
return !String.IsNullOrEmpty(txtFName) && !String.IsNullOrEmpty(txtLName) && !String.IsNullOrEmpty(txtEMail);
}
Or
protected bool ValidateProfile()
{
bool returnValue = true;
if(String.IsNullOrEmpty(txtFName))
{
returnValue=false;
}
else if(String.IsNullOrEmpty(txtLName))
{
returnValue = false;
}
else if(String.IsNullOrEmpty(txtEMail))
{
returnValue = false;
}
return returnValue;
}
Though you could just return false as soon as you find an invalid field.
Not a C# programmer, but can't you just write:
return (txtFName != "") && (txtLName != "") && (txtEMail != "");
for the body of the function?

Categories

Resources