C# false input returned after second try - c#

Hello I'm new to C# and started learning it yesterday with some Java and Python knowledge. I tried to make a calculator but it isn't working as expected.
The code is:
using System;
namespace LolCS{
class Program{
static void Main(){
//variables and objects
Program proj = new Program();
double solution = 0;
string operation;
double input1 = 0;
double input2 = 0;
//take inputs for input 1,2 and which operation to use
Console.WriteLine("Welcome to this calculator, let's get started\n"+
"Please input your operations\n");
double.TryParse(proj.get_input("in1"), out input1);
operation = proj.get_input("op");
double.TryParse(proj.get_input("in2"), out input2);
//call function which does the math and assign result to variable solution
solution = proj.domath(operation, input1, input2);
//print solution
Console.WriteLine(input1+operation+input2+" = "+solution);
if (Console.ReadLine() == "r") { Main(); }
}
//function to do the math according to the given operation
double domath(string oper, double in1, double in2){
double solu = 0;
switch(oper){
case "+":
solu = in1 + in2;
break;
case "-":
solu = in1-in2;
break;
case "*":
solu = in1 * in2;
break;
case "/":
solu = in1 / in2;
break;
}
return solu;
}
//gets values for the variables
string get_input(string in_type){
string gon_ret = "";
switch(in_type){
case "in1":
Console.WriteLine("Input 1: ");
gon_ret = Console.ReadLine();
break;
case "in2":
Console.WriteLine("Input 2: ");
gon_ret = Console.ReadLine();
break;
case "op":
Console.WriteLine("Operation: ");
gon_ret = Console.ReadLine();
if (!(gon_ret == "+") && !(gon_ret == "-") && !(gon_ret == "*") && !(gon_ret == "/")){
Console.WriteLine(gon_ret+" Not Valid, try again");
get_input("op");
}
break;
}
return gon_ret;
}
}
}
The problem is with this line of code:
case "op":
Console.WriteLine("Operation: ");
gon_ret = Console.ReadLine();
if (!(gon_ret == "+") && !(gon_ret == "-") && !(gon_ret == "*") && !(gon_ret == "/")){
Console.WriteLine(gon_ret+" Not Valid, try again");
get_input("op");
}
break;
It is expected to check if the input for operation is different than +,-,* or / and if it is it should print "Not Valid" and repeat the input for the operation. That works as expected if the input is correct the first time but if the correct input is given on the second try or later, the false input is returned. Example output:
Welcome to this calculator, let's get started
Please input your operations
Input 1:
2
Operation:
p
p Not Valid, try again
Operation:
+
Input 2:
3
2p3 = 0
Sorry if it is a stupid mistake but I'm still learning. Thanks for the help!

You are doing a recursive operation with get_input("op") The function works fine but you are not returning the results of the new get_input("op") call. You are returning the invalid string produce from the original call.
case "op":
Console.WriteLine("Operation: ");
gon_ret = Console.ReadLine();
if (!(gon_ret == "+") && !(gon_ret == "-") && !(gon_ret == "*") && !(gon_ret == "/")){
Console.WriteLine(gon_ret+" Not Valid, try again");
//Return here as the current call is invalid
return get_input("op");
}
break;

Related

Adding switch case

I want to add switch case to not allow the user to write string when entering temperature or when there is nothing to delete it says "there is nothing to delete, go back to menu".
List<string> Temp = new List<string>();
while (true)
{
string val;
Console.WriteLine("[L] ägg till temp-mätning: ");
Console.WriteLine("[S] kriv ut alla temperaturer och medeltemperatur");
Console.WriteLine("[T] ag bort temp-mätning");
Console.WriteLine("[A] vsluta");
Console.Write("Selection: ");
val = Console.ReadLine();
if (val == "l" || val == "L")
{
Console.WriteLine("add temperature : ");
Temp.Add(Console.ReadLine());
Console.Clear();
}
else if(val == "s" || val == "S")
{
int index = 1;
Console.Clear();
Console.WriteLine($"Your temperatures are: ");
Temp.ForEach(x => Console.WriteLine($"{index++} - {x}"));
}
else if (val == "t" || val == "T")
{
Console.Write($"Which temp do you want to delete [index from 1 to {Temp.Count}]: ");
int deleteIndex = int.Parse(Console.ReadLine()) - 1;
Temp.RemoveAt(deleteIndex);
}
else
{
Console.WriteLine("incorrect input: ");
Console.Clear();
break;
}
To control use input you can extract methods, e.g.
private static int ReadInteger(string title) {
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
if (int.TryParse(Console.ReadLine(), out int result))
return result;
Console.WriteLine("Incorrect syntax, please, try again.");
}
}
then you can put
val = Console
.ReadLine()
.Trim() // Let's be nice and tolerate leading / trailing spaces, e.g. " L "
.ToUpper();
val = val.Substring(0, Math.Max(1, val.Length));
switch (val) {
case "L":
// We read valid integer, turn it to string and out to Temp
Temp.Add(ReadInteger("add temperature : ").ToString());
Console.Clear();
break;
case "T":
int deleteIndex = ReadInteger(
"$"Which temp do you want to delete [index from 1 to {Temp.Count}]: ");
if (deleteIndex >= 0 && deleteIndex < Temp.Count)
Temp.RemoveAt(deleteIndex);
else
Console.WriteLine("Index out of range");
break;
...
}
Please check C# reference websites or books before asking questions.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/
Here is the code you wanted, hope this helps you:
List<string> Temp = new List<string>();
while (true)
{
menu:
string val = string.Empty;
Console.WriteLine("[L] ägg till temp-mätning: ");
Console.WriteLine("[S] kriv ut alla temperaturer och medeltemperatur");
Console.WriteLine("[T] ag bort temp-mätning");
Console.WriteLine("[A] vsluta");
Console.Write("Selection: ");
val = Console.ReadLine();
switch (val.ToLower())
{
case "l":
addTemperature:
Console.WriteLine("add temperature : ");
string temperatureInput = Console.ReadLine();
int temperatureToAddToList;
try
{
temperatureToAddToList = Convert.ToInt32(temperatureInput); //This line trys to convert string variables to integer variables. If string variable includes any character, it will throw an exception.
}
catch (Exception error) //If an exception was thrown, this code block gets activated, which will give out the message you asked for.
{
Console.Clear();
Console.WriteLine("Please enter a number instead of a string!");
goto addTemperature;
}
Temp.Add(temperatureInput.Trim());
Console.Clear();
break;
case "s":
int index = 1;
Console.Clear();
Console.WriteLine($"Your temperatures are: ");
Temp.ForEach(x => Console.WriteLine($"{index++} - {x}"));
break;
case "t":
if (Temp.Count == 0)
{
Console.Clear();
Console.WriteLine("There is nothing to delete, go back to menu.");
goto menu;
}
else
{
Console.Write($"Which temp do you want to delete [index from 1 to {Temp.Count}]: ");
int deleteIndex = int.Parse(Console.ReadLine()) - 1;
Temp.RemoveAt(deleteIndex);
break;
}
default:
Console.WriteLine("incorrect input: ");
Console.Clear();
break;
}
I have revised and updated my code example to better solve your problem.

Going back/forward to a command in C#

Console.WriteLine('What is your name, traveler?');
string mainName = Console.ReadLine();
Console.WriteLine('So, your name is ' + mainName + ' ? y/n');
char ans = Console.ReadKey;
if (ans == y)
{
Console.WriteLine('Nice, let me introduce myself now.');
}
else if(ans == n)
{
}
else
{
Console.WriteLine('Please insert either y or n.');
}
In the code above, how can I make it so that the else if statement will return to the third line and the else statement will return to the first line of the code and continue running from there?
You can try to use do....While(true) loop
Console.WriteLine("What is your name, traveler?");
string mainName = Console.ReadLine();
Console.WriteLine("So, your name is " + mainName + " ? y/n");
do
{
var ans = Console.ReadKey(true).Key;
if (ans == ConsoleKey.Y)
{
Console.WriteLine("Nice, let me introduce myself now.");
break;
}
else if (ans == ConsoleKey.N)
{
break;
}
Console.WriteLine("Please insert either y or n.");
} while (true);
Note
I would use Console.ReadKey(true).Key to get keyboard input value,because it's enum.

Error when trying to do math equation

I am new to Console Application, I usually use C# for Unity. The code doesn't really work how I want it
Yes I know using Goto isn't good. But I don't know alternatives
I had [ a = 2 ] [ b = 3 ] and [ ans = a+b ] so the obvious answer is 5. So when you put 5 it runs the Else statement which is getting it incorrect.
goto start;
error:
Console.Clear();
Console.WriteLine("Input not Recognized");
Console.WriteLine("Try Again");
Console.WriteLine("\nType (Reset) to Reset Program");
Console.WriteLine("\nType (End) to End Program");
Console.WriteLine("");
string error1 = Console.ReadLine();
if (error1.Equals("reset", StringComparison.InvariantCultureIgnoreCase))
{
goto start;
}
if (error1.Equals("end", StringComparison.InvariantCultureIgnoreCase))
{
Environment.Exit(0);
}
else
{
goto error;
}
start:
Console.WriteLine("Solve the Math Equation");
int a = 2;
int b = 3;
int ans = a + b;
Console.WriteLine("\n2 + 3");
Console.WriteLine("");
string user = "";
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace)
{
double val = 0;
bool _x = double.TryParse(key.KeyChar.ToString(), out val);
if (_x)
{
user += key.KeyChar;
Console.Write(key.KeyChar);
}
}
else
{
if (key.Key == ConsoleKey.Backspace && user.Length > 0)
{
user = user.Substring(0, (user.Length - 1));
Console.Write("\b \b");
}
}
}
while (key.Key != ConsoleKey.Enter);
if (user.Equals(ans))
{
Console.Clear();
Console.WriteLine("Correct!");
Console.WriteLine("\nYour answer " + ans);
Console.WriteLine("\nType (End) to End Program");
Console.WriteLine("");
string end1 = Console.ReadLine();
if (end1.Equals("end", StringComparison.InvariantCultureIgnoreCase))
{
Environment.Exit(0);
}
else
{
goto error;
}
}
else
{
Console.Clear();
Console.WriteLine("Incorrect!");
Console.WriteLine("\nThe answer was " + ans);
Console.WriteLine("\nType (Reset) to Reset Program");
Console.WriteLine("Type (End) to End Program");
Console.WriteLine("");
string rne1 = Console.ReadLine();
if (rne1.Equals("reset", StringComparison.InvariantCultureIgnoreCase))
{
Console.Clear();
goto start;
}
if (rne1.Equals("end", StringComparison.InvariantCultureIgnoreCase))
{
Environment.Exit(0);
}
else
goto error;
Your user and ans are not equal in your code which is why your code jumps to the error. The reason why they are not equal are their Types.
user is a string
ans is an integer
So you are comparing "5" to 5 and that can not be equal.
Convert one of the variables so you have the same type.
Either use user.Equals(ans.ToString()) in the if statement or convert the string to a number (which is the better solution IMO - because it also handles the situation when the input is not a number). Like this:
int userAns;
if (!Int32.TryParse(user, userAnsj))
Console.WriteLine("Input is not a valid integer.");
and then comapare userAns to ans.

C# error: the out parameter must be assigned to before control leaves the current method [duplicate]

This question already has answers here:
Error : The Out Parameter must be assigned before control leaves the current method
(2 answers)
Closed 7 years ago.
The variable the error is referring to is aNumber on line (32,17), how can I fix this?
using System;
class Calculation
{
public static void Main(string[] data)
{
double result = Convert.ToDouble( data[0]);
char op;
double number;
GetData(out op, out number);
while (op != 'q' && op != 'Q')
{
switch (op)
{
case '+':
result += number;
break;
case '-':
result -= number;
break;
case '*':
result *= number;
break;
case '/':
result /= number;
break;
}
Console.WriteLine("Result = " + result.ToString());
GetData(out op, out number);
}
}
static void GetData(out char anOperator, out double aNumber)
{
string line;
Console.Write("Enter an opertor and a number or 'q' to quit: ");
line = Console.ReadLine();
anOperator = Convert.ToChar(line.Substring(0, 1));
if (anOperator != 'q' && anOperator != 'Q')
aNumber = Convert.ToDouble(line.Substring(2));
}
}
Add this to GetData method:
aNumber = 0;
Like this:
static void GetData(out char anOperator, out double aNumber)
{
string line;
Console.Write("Enter an opertor and a number or 'q' to quit: ");
line = Console.ReadLine();
anOperator = Convert.ToChar(line.Substring(0, 1));
if (anOperator != 'q' && anOperator != 'Q')
aNumber = Convert.ToDouble(line.Substring(2));
else
aNumber = 0;
}

How to implement a safety net so that my program does not crash when incorrect format is input

This is my C# program for taking a number and then an operator and another number that the user enters and then doing a simple calculation, how would I go about implementing a safety net so that no matter what the users enters, whether it be nothing or a string of unwanted characters, the program will say invalid input, try again. right now it crashes if the exactly correct input is not entered. thanks in advance. Please explain the location in my code where it would be best to implement this and the flow of logic.
using System;
class Calculation
{
public static void Main(string[] data)
{
double result = Convert.ToDouble(data[0]);
char op;
double number;
GetData(out op, out number);
while (op != 'q' && op != 'Q')
{
switch (op)
{
case '+':
result += number;
break;
case '-':
result -= number;
break;
case '*':
result *= number;
break;
case '/':
result /= number;
break;
}
Console.WriteLine("Result = " + result.ToString());
GetData(out op, out number);
}
}
static void GetData(out char anOperator, out double aNumber)
{
aNumber = 0;
string line;
Console.Write("Enter an opertor and a number or 'q' to quit: ");
line = Console.ReadLine();
anOperator = Convert.ToChar(line.Substring(0, 1));
if (anOperator != 'q' && anOperator != 'Q')
aNumber = Convert.ToDouble(line.Substring(2));
}
}
You may want to look into the Double.TryParse() method. Personally I wouldn't recommend using exceptions for user input - invalid user input is not an exceptional situation in my opinion, but something you should expect all the time. There are probably some edge cases that I missed that should be solved with exception handling - can't think of any right now.
Basically the idea here is to check all the conditions you can think of and don't let exceptions bubble up.
I'm employing the TryXXX() pattern in here. I introduced a string to get the error message from the method that gets the user input in case the input is invalid. By the way, I also replaced your loop with a do-while.
public static void Main(string[] data)
{
if(data.Length == 0)
{
Console.WriteLine("No input :(");
return;
}
double result;
if(!Double.TryParse(data[0], out result))
{
Console.WriteLine("Invalid input: " + data[0]);
return;
}
Console.WriteLine("Starting with number: " + result);
char op;
double number;
string errorMessage;
do
{
if(!TryGetData(out op, out number, out errorMessage))
{
Console.WriteLine("Invalid input: " + errorMessage);
continue;
}
switch (op)
{
case '+':
result += number;
break;
case '-':
result -= number;
break;
case '*':
result *= number;
break;
case '/':
result /= number;
break;
default:
Console.WriteLine("Invalid operator: " + op);
continue;
}
Console.WriteLine("Result = " + result.ToString());
} while (Char.ToLower(op) != 'q');
}
static bool TryGetData(out char anOperator, out double aNumber, out string message)
{
aNumber = 0;
message = null;
Console.Write("Enter an operator and a number or 'q' to quit: ");
var line = Console.ReadLine();
anOperator = line[0];
if (anOperator != 'q' && anOperator != 'Q')
{
if(line.Length <= 2)
{
// string too short
message = "Input string too short";
return false;
}
var isValidNumber = Double.TryParse(line.Substring(2), out aNumber);
if(!isValidNumber)
{
message = "Invalid number: " + line.Substring(2);
return false;
}
if(isValidNumber && (anOperator == '/' && aNumber == 0))
{
message = "Cannot divide by 0.";
return false;
}
}
return true;
}
this is called Exception handling ... You can use try/catch like this
try
{
string mystring = "this is a string and can't be converted to int ";
int myint = int.Parse(mystring);
}
catch
{
Console.WriteLine("Please Enter a vaild Data Type");
}
this way the app won't crush , instead it will display any error message you want

Categories