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

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

Related

How to ask until the user get specific reply in C#

{
bool stayInLoop = true;
while(stayInLoop)
{
Console.WriteLine("Enter Yor Number");
var PlusA = Console.ReadLine();
Console.WriteLine("Enter Yor Number");
var PlusB = Console.ReadLine();
if(PlusA == ';')
{
stayInLoop = false;
break;
}
else if(PlusB == ';')
{
stayInLoop = false;
break;
}
else
{
Console.WriteLine("Answer =");
Console.WriteLine(PlusA + PlusB);
}
}
}
I want to make a plus calculator, I want to let the user type more then 2 numbers, keep asking for PlusC, PlusD, until they type the symbol ; .
For example the user numbers in PlusA PlusB PlusC and in PlusD, he/she type ; so it should print PlusA + PlusB + PlusC
If he type a number in PlusD, it should ask for PlusE, until he/she type ;, it should sum up all the number before
And I want to auto the process, The program will ask for PlusA to PlusZ itself instead of int it my own, how to do that? (I know I am not saying it clearly, coz i can't find better words)
You want to add numbers until the user enters ;. You should use loops for that. Here's the complete solution that uses a for loop:
switch(exp)
{
case "+":
{
var sum = 0;
for(;;)
{
Console.WriteLine("Enter Yor Number");
var line = Console.ReadLine();
if (line == ";") break;
sum += Convert.ToInt32(line);
}
Console.WriteLine(sum);
break;
}
}
Here we repeat the part inside the loop over and over, accumulating entered numbers into sum variable until the user enters ; - that's when we end the loop with break.
Use a while loop:
switch(exp)
{
case "+":
int sum = 0;
string input = "";
do
{
Console.WriteLine("Enter your number:");
input = Console.ReadLine();
if (input != ";")
sum += int.Parse(input);
} while (input != ";");
Console.WriteLine("Answer =" + sum);
break;
}
You are having problems because you should iterate the code until your exit/end condition is met using the while statement.
switch(exp)
{
case "+":
int mySum = 0;
string userInput = "";
while(userInput != ";")
{
Console.WriteLine("Enter number to add (';' to end the sum):");
userInput = Console.ReadLine();
if (userInput != ";")
{
// Would be interesting checking if entered really is an integer, for example Int32.TyParse()
mySum = mySum + Convert.ToInt32(userInput);
}
}
Console.WriteLine("Answer =" + mySum.ToString());
break;
}
Thankyou for your reply, but is there any way to auto the process, The program will ask for PlusA to PlusZ itself instead of int it my own
bool stayInLoop = true;
while(stayInLoop)
Console.WriteLine("Enter Yor Number");
var PlusA = Console.ReadLine();
Console.WriteLine("Enter Yor Number");
var PlusB = Console.ReadLine();
if(PlusA == ';')
{
stayInLoop = false;
break;
}
else if(PlusB == ';')
{
stayInLoop = false;
break;
}
else
{
Console.WriteLine("Answer =");
Console.WriteLine(PlusA + PlusB);
}
}
and when I run this, it run out 'error CS0019' and 'error CS0139'
What you're looking for is a while() loop.
example:
bool stayInLoop = true;
while(stayInLoop) // basically means (stayInLoop == true)
{
var text = Console.ReadLine();
if(text == ';')
{
stayInLoop = false;
break; // break will stop the loop, but you can also change the variable to false to break the loop.
}
}

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.

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.

Replacing certain letters with symbol

I'm doing an assignment for school which includes replacing every letter except A,a,S,s,N,n in a string.
So far I figured out how to replace these letters, which is the opposite of the assignment.
Can someone help?
This is what I have rn.
string texti = null;
Console.WriteLine ("");
Console.WriteLine ("Put in your sentence ..");
texti = Console.ReadLine();
Console.WriteLine ("You entered the following ..");
Console.WriteLine (texti);
texti = texti.Replace ("a", "*").Replace ("A", "*").Replace ("s", "*").Replace ("S", "*").Replace ("N", "*").Replace ("n", "*");
Console.WriteLine ("Your new text");
Console.WriteLine (texti);
but again .. this above is the opposite of my assignment
Here I have a similar project, but this replaces everything with #
Console.WriteLine();
for (int i = 0; i < text.Length; i++)
{
newtext = newtext + "#";
}
Console.WriteLine(newtext);
Console.ReadLine();
You can use LINQ:
var letters = "AaSsNn";
var result = String.Join("", input.Select(c => letters.Any(x => x == c) ? c : '*'));
Use a simple loop to build a new string. but with some checks and modifications.
string text = Console.ReadLine();
string newText = "";
string ommit = "AaSsNn"; // should not remove these.
for (int i = 0; i < text.Length; i++)
{
if (ommit.Contains(text[i])) // if character exist in ommit.
{
newText += text[i]; // put the original
}
else
{
newText += "*"; // replace
}
}
You can use a bit longer condition instead of using string like ommit.
if(text[i].ToString().ToUpper() == "A" ||
text[i].ToString().ToUpper() == "S" ||
text[i].ToString().ToUpper() == "N")
string texti = string.Empty;
Console.WriteLine("");
Console.WriteLine("Put in your sentence ..");
texti = Console.ReadLine();
Console.WriteLine("You entered the following ..");
Console.WriteLine(texti);
foreach (char str in texti)
{
switch (str)
{
case 'A':
case 'a':
case 'S':
case 's':
case 'N':
case 'n':
{
break;
}
default:
{
texti = texti.Replace(str, '*');
break;
}
}
}
Console.WriteLine("Your new text");
Console.WriteLine(texti);

How to check user input with if command

Not sure if I'm overlooking something really simple but I'm trying to make a program that allows a user to enter 1 of 2 letters and then run code based on the input. Seems simple enough but I've run into several errors with all the ways I thought this could work. Here is the code:
string name = (Console.ReadLine());
Console.WriteLine("Is " + name + " ok?");
Console.WriteLine("\n(Y)es\n(N)o");
char ansys = Console.ReadKey();
if (ansys = ConsoleKey.Y)
Console.Clear();
else
{
Console.WriteLine();
Console.WriteLine("Enter letters only");
}
I added in the else portion (unfinished)just to get an idea if If i'm going the right direction with the intended goal as well. Would I be able to make an else statement that triggers if neither Y or N is pressed this way?
Well, first of all, you are making an assignment, not comparing:
if (ansys.Key = ConsoleKey.Y)
is wrong, use:
if (ansys.Key == ConsoleKey.X)
== is comparison, = is assignment. Don't confuse them, it may cause serious problems.
For you question, if you simply add an else if statement checking for "No" answer, then else statement won't be triggered if Y or N is pressed. If at least if statement is executed, else statement won't be executed.
Your code should look like:
if (ansys == ConsoleKey.Y) {
// code if yes
}
else if (ansys == ConsoleKey.N) {
// code if no
}
else {
// code if neither
}
Edit:
Since my primary language is not C#, I looked at documentation to check my answer. I figured out that if you use ReadKey() it does not return a ConsoleKey, it returns struct ConsoleKeyInfo. You need to use Key member of the ConsoleKeyInfo to access the pressed key. Please re-check the code.
Try this approach:
ConsoleKeyInfo cki;
cki = Console.ReadKey();
if (cki.Key == ConsoleKey.Y)
{
Console.Clear();
}
else if (cki.Key == Console.N)
{
Console.Clear();
}
else
{
Console.WriteLine();
Console.WriteLine("Enter letters only");
}
You can find th examples here: ReadKey - examples
Try this:
string name = (Console.ReadLine());
Console.WriteLine("Is " + name + " ok?");
Console.WriteLine("\n(Y)es\n(N)o");
var ansys = Console.ReadKey();
if (ansys.KeyChar == 'y' || ansys.KeyChar == 'Y')
{
//Handle yes case
}
if (ansys.KeyChar == 'n' || ansys.KeyChar == 'N')
{
//Handle no case
}
else
{
Console.WriteLine();
Console.WriteLine("Enter letters only");
}
Try this (couldnt test it)
This will ask for the name until the confirmation answer is Y
If the input when asked Y or N is another thing, it will ask again for the name confirmation.
string name = "";
while (name.equals(""))
{
name = (Console.ReadLine());
Console.WriteLine("Is " + name + " ok?");
String answer = "";
while(answer.equals(""))
{
Console.WriteLine("\n(Y)es\n(N)o");
char ansys = Console.ReadKey();
if (ansys == ConsoleKey.Y || ansys == ConsoleKey.N)
{
answer = ansys.ToString();
Console.Clear();
}
else
{
Console.WriteLine();
Console.WriteLine("Enter letters only!!");
}
}
if(!answer.equals("Y"))
name = "";
}
Im not sure if ansys.ToString() is a valid method, and if that returns the "Y" string in case the key pressed was Y

Categories

Resources