I'm working on a simple password storage console application in c#.
I'm having a bit of a problem on a section that asks if the user would like to mask all password entries from that point on.
This is the section of code:
bool tryagain = true;
while(tryagain == true)
{
Console.WriteLine("Would you like to mask all other password entiries?(Y,N)");
string input = Console.ReadLine();
if (input == "y" | input == "Y")
//Something wrong, always passes to Your awnser was invalid
{
maskpass = true;
tryagain = false;
}
if (input == "n" | input == "N")
{
maskpass = false;
tryagain = false;
}
else
{
Console.WriteLine("Your awnser was invalid, would you like to try again?");
string yesno = Console.ReadLine();
if (yesno == "y" | yesno == "Y")
{
tryagain = true;
}
if (yesno == "n" | yesno == "N")
{
Environment.Exit(0);
}
}
}
The problem is when I run the code it always runs to the else statement.
I'm certain the mistake is very simple and I'm just being ignorant but anyone have any idea on whats going on here?
Use || instead of single |. The || mean or conditional, but single | is binary or.
I assume that the logic of your code says:
if input=='y' OR input=="Y", do something.
Another suggession yet. If my assumption right, you can achiev that with simple String.Equals overload:
if(input.Equals("y", StringComparison.InvariantCultureIgnoreCase)
{
//do something/
}
You can either use || or you can use the method of the String class String.equals. Since it is a String you are reading as input better use the String.equals method
Related
I have a list of existing products presented in a datagridview. User can add new product using this window
Some of the fields can be accepted as empty. The text field must have char only and the int fields must have positive int only. ID, price, playtime and status must be positive ints. The rest must be chars, when they aren't empy that is. The code i have works but only when every field that could be empty is empty. It doesn't work if some are and others aren't.
It would also be nice if you could solve the issue of accepting empty int fields.myint.ToString().Length; is not getting the job done seems like. Maybe the answer is easy but I'm sorta new to C# and .Net.
Here is the code i wrote
if (!plist.type.Any() || !plist.author.Any() || !plist.genre.Any() || !plist.format.Any() || !plist.language.Any() || !plist.platform.Any())
{
if (plist.id != Math.Abs(plist.id) || plist.price != Math.Abs(plist.price)
|| plist.playtime != Math.Abs(plist.price) || plist.status != Math.Abs(plist.price))
{
DialogResult = DialogResult.No;
}
else if (plist.type.Any(char.IsDigit) || plist.name.Any(char.IsDigit)
|| plist.author.Any(char.IsDigit) || plist.genre.Any(char.IsDigit)
|| plist.format.Any(char.IsDigit) || plist.language.Any(char.IsDigit) || plist.platform.Any(char.IsDigit))
{
DialogResult = DialogResult.No;
}
else
{
DialogResult = DialogResult.OK;
}
}
else
{
DialogResult = DialogResult.OK;
}
Let me know if there is anything left to clear up.
I appreaciate any suggestions you got for me!
Assuming that type, author, genre, format, language and platform are mandatory fields, you should be setting DialogResult to DialogResult.No instead of OK in your bottom most else statement. Otherwise, you will be skipping your logic and returning the wrong result.
if (!plist.type.Any() || !plist.author.Any() || !plist.genre.Any() || !plist.format.Any() || !plist.language.Any() || !plist.platform.Any())
{
if (plist.id != Math.Abs(plist.id) || plist.price != Math.Abs(plist.price)
|| plist.playtime != Math.Abs(plist.price) || plist.status != Math.Abs(plist.price))
{
DialogResult = DialogResult.No;
}
else if (plist.type.Any(char.IsDigit) || plist.name.Any(char.IsDigit)
|| plist.author.Any(char.IsDigit) || plist.genre.Any(char.IsDigit)
|| plist.format.Any(char.IsDigit) || plist.language.Any(char.IsDigit) || plist.platform.Any(char.IsDigit))
{
DialogResult = DialogResult.No;
}
else
{
DialogResult = DialogResult.OK;
}
}
else
{
DialogResult = DialogResult.No;
}
As for the empty integer length issue, make sure that you are not trying to turn a null value to a string. Consider using a numericUpDown instead of a textbox as the numericUpDown is designed to work with numbers. You can even set limits to you numbericUpDown, like a lower number limit to prevent negative numbers.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.numericupdown?view=windowsdesktop-7.0
First things first, I am an absolute beginner to c# so excuse me for any dumb mistakes I have done.
currently, I am making a "banking system" as my beginner project. I am getting a frustrating error
with entering a key.
var input = Convert.ToString(Console.ReadKey());
if (input == "E") {
Console.WriteLine("English has been selected");
}
if (input == "A")
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else {
Console.WriteLine("Error!");
}
if I input E or A the console only displays the Else condition instead of the two if conditions. side note: vscode doesn't show any errors relating to this.
In your code you are using ReadKey() - but you must be sure to use it properly. It's not quite as simple as say Python input() but C#'s ReadKey() does a good job once you understand it.
First, and most importantly, you need to know that ReadKey() does not just return a letter (like 'a', or 'b'), and it does not even return a numeric key code (like 9 or 10). Instead, it returns something called a ConsoleKeyInfo. Technically, it is a struct, but you can just think of it as "information about the key pressed".
Second, because your goal is to know what key was pressed and specifically if it was an A or E, you can get the Key property from the ConsoleKeyInfo. But once again, we are not getting a letter (like 'a' or 'b'), or strictly speaking an integer (like 9 or 10) - . The Key we get is an Enum or more specifically a ConsoleKey Enum. So at this point we can either check the enum value directly, or convert it to a string representation and check it against a string value (such as "A" or "E").
Now, all of this can seem overkill for a tiny little program - but overall it provides a lot of benefit for writing safe and reliable programs. To compare it with something similar, it is like using a FileInfo object to represent a file, rather than just a using string for a filepath. But I do encourage you to read the docs referenced below because when you understand how to make use of documentation (and debugging tools) you have what you need to figure out most of this on your own!
tldr;
ReadKey() returns ConsoleKeyInfo struct, which we can use to get a Key property. Since the Key property returns an Enum, not a character or a string, we either check the value of the enum directly, or take one more step of calling ToString() on the ConsoleKeyEnum to convert it to a "letter" or "key" in string form. Additionally, the ConsoleKeyInfo class exposes a KeyChar property that may be used instead.
Reference: https://learn.microsoft.com/en-us/dotnet/api/system.console.readkey?view=net-6.0
sample revised code
var input = Console.ReadKey();
if (input.Key.ToString() == "E")
{
Console.WriteLine("English has been selected");
}
else if (input.Key.ToString() == "A")
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else
{
Console.WriteLine("Error!");
}
Because we are working with Enums, it is really simpler and safest to use them in the comparisons directly:
var input = Console.ReadKey();
if (input.Key == ConsoleKey.E)
{
Console.WriteLine("English has been selected");
}
else if (input.Key == ConsoleKey.A)
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else
{
Console.WriteLine("Error!");
}
Additionally we have the option to use the KeyChar property (this one does, however, return characters, not strings, and case matters - so we can get 'A', or 'a' depending on if shift is used or not).
var input = Console.ReadKey();
if (input.KeyChar == 'E' || input.KeyChar == 'e')
{
Console.WriteLine("English has been selected");
}
else if (input.KeyChar == 'A' || input.KeyChar == 'a')
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else
{
Console.WriteLine("Error!");
}
The simplest solution is to simply use Console.ReadLine() instead of Console.ReadKey(). This will require the user to press enter after they have selected wither A or E but this is more user friendly when selecting an option as it gives you the chance to confirm your choice.
var input = Convert.ToString(Console.ReadLine());
if (string.Equals(input, "E", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("English has been selected");
}
else if (string.Equals(input, "A", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else
{
Console.WriteLine("Error!");
}
I also added a invariant string check to ignore case (so that "a" and "A" would both be accepted for example) and added a else to the second if statement as general improvements.
Note: Your use of Console.ReadKey() didn't work because it returns a struct that holds information about the input key - this struct will not convert into the original input key if you call Convert.ToString() on it.
If you do really prefer to use Console.ReadKey() then just access the input character using Console.ReadKey().KeyChar.
var input = Convert.ToString(Console.ReadKey().KeyChar);
if (string.Equals(input, "E", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("English has been selected");
}
else if (string.Equals(input, "A", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else
{
Console.WriteLine("Error!");
}
Try this please:
using System;
class Program
{
public static void Main (string[] args)
{
string input = Console.ReadLine();
if (input == "E")
{
Console.WriteLine("English has been selected");
}
else if (input == "A")
{
Console.WriteLine("تم اختيار اللغة العربية");
}
else
{
Console.WriteLine("Error!");
}
}
}
string question1;
//Question 1
WriteLine("What is his favourite sport? ");
WriteLine("a) Soccer");
WriteLine("b) Basketball ");
WriteLine("c) Tennis ");
WriteLine("d) Football " );
Write("your answer is: ");
question1 = ReadLine();
if (question1 != "a" || question1 != "b" || question1 != "c")
Write("That is incorrect try again");
else
Write("that is correct");
No matter what letter I put it always gives me an incorrect try again, what am I doing wrong? Also would a while loop be better when trying to create a quiz game?
Those "or" (||) operators should almost certainly be "and" (&&) operators.
Think of what happens when you enter c, for example. Obviously, that will be c but it won't be a or b, so two of the sub-conditions will be true.
In fact, that's the case no matter which of a, b, or c that you enter (if you enter something else, all three will be true). And since an x || y || z is true if any of its sub-components is true, the expression as a whole is always true. The following table hopefully illustrates this:
Input
!= "a" (A)
!= "b" (B)
!= "c" (C)
A or B or C
a
False
True
True
True
b
True
False
True
True
c
True
True
False
True
d
True
True
True
True
other
True
True
True
True
In other words, unless question1 is some sort of "Schrodinger's variable" that can be all of a, b, and c at the same time, that if statement of yours will never be false.
However, if the subject's favourite sport is football, I'm not sure why you wouldn't just use the much simpler condition below:
if (question1 == "d") {
WriteLine("That is correct");
} else {
WriteLine("That is incorrect try again");
}
That approach (accepting the right answer) seems far easier than what your original code seems to be doing (rejecting all of the the wrong answers).
And, yes, a while loop probably would be better for a quiz scenario, something like the following would be a good start.
I've even added a rudimentary scoring system, because I get bored easily :-)
The points for a question reduce if you answer wrongly: two points for a correct answer first time, one point if you get it right second time, no points otherwise:
int score = 0; // Done once before ALL questions.
int awardPoints;
string answer;
awardPoints = 2; // Done before EACH question.
do {
// Output the question and get an answer.
WriteLine();
WriteLine("What is his favourite sport (x to exit)? ");
WriteLine(" a) Soccer");
WriteLine(" b) Basketball");
WriteLine(" c) Tennis");
WriteLine(" d) Football" );
Write("Your answer: ");
answer = ReadLine();
// Evaluate answer (d is correct here). An x answer
// will produce no output as it assumes you want to
// just exit.
if (answer == "d") {
score += awardPoints;
WriteLine("Correct, you earned {} points, now at {}",
awardPoints, score);
} else if (answer != "x") {
// Incorrect answer. Halve question points so
// user cannot simply keep trying without
// some penalty.
WriteLine("Incorrect, try again");
awardPoints = awardPoints / 2;
}
} while (answer != 'd' && answer != 'x');
// Here, either the correct answer or 'x' was
// given. If 'x', probably want to stop asking
// questions. Otherwise go on to next question.
Please, try this way.
void Main()
{
string question1 = "";
do
{
//Question 1
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("What is his favourite sport? ");
Console.WriteLine("a) Soccer");
Console.WriteLine("b) Basketball ");
Console.WriteLine("c) Tennis ");
Console.WriteLine("d) Football ");
Console.Write("your answer is: ");
question1 = Console.ReadLine();
Console.WriteLine(question1);
if (question1 == "a" || question1 == "b" || question1 == "c")
{
Console.Write("That is incorrect try again");
}
else
{
Console.Write("that is correct");
}
} while (question1 != "q");
}
When you use || operator, as soon as any condition is true, it stops processing rest of the cases and marks the statement as true.
The best way is, to test the correct answer and put rest of the cases in else block and mark them as 'incorrect'
if (question1 == 'correctOption')
{
System.Console.Write("That is correct.");
}
else
{
System.Console.Write("That is incorrect try again");
}
The runtime evaluates from left to right. In case of || it stops at the first true and returns true. If there is nothing which is true then it returns false.
In case of && it stop at the first false and returns false.
The readable code if to check for right answer and say correct and for all others display incorrect. This will also take care of user entering any other value other than "a","b,"c" as well like say "t"
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 don't know if it is just me being thick but I have a bit of validation code to check for a yes or no answer.
I can't seem to get it to work I have used the code in other places in my program and it works but I can't spot the error if there is one. The code runs through the while anyway no mater what the input character is.
string correctDestenation = Console.ReadLine().ToLower();
while (correctDestenation != "y" || correctDestenation != "n")
{
Console.WriteLine(
"Oops! You must enter a 'y' for yes and a 'n' for no");
correctDestenation = Console.ReadLine().ToLower();
}
Your logic is incorrect. You want to use && instead of ||.
while (correctDestenation != "y" && correctDestenation != "n")
or, you can use De Morgan's Law and look at it the other way, which is equivalent:
while (!(correctDestenation == "y" || correctDestenation == "n"))
That condition will always be satisfied, as a character will not be equal to 'y' or equal to 'n'. Use && instead of ||.
How about you use the AND operator
while (correctDestenation != "y" && correctDestenation != "n")
{
Console.WriteLine("Oops! You must enter a 'y' for yes and a 'n' for no");
correctDestenation = Console.ReadLine().ToLower();
}