My code works, but I don't fully understand how - c#

using System;
namespace SimpleweightConversion
{
public class PoundstoKilos
{
public static void Main()
{
double pounds = 0.0;
Console.Write("How many pounds? ");
double.TryParse(Console.ReadLine(), out pounds);
double kilograms = pounds * 0.453592;
Console.WriteLine("{0} pounds is equal to {1} kilograms", pounds,
kilograms);
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
}
}
I'm trying to learn C# and I created this code to convert from pounds to kilograms, I added the tryparse bit to avoid an error if the user throws something other than numbers at the program, and it works!.The only problem I have is it doesn't clearly show when does it assign the user's input to the pounds variable, because at the start, the value of the pounds variable is 0.0, but at some point, the value provided by the user is assigned to the pounds variable, or at least that's what I think is happening.

From the Microsoft Docs, the syntax for TryParse() is:
public static bool TryParse(
string s,
out double result
)
This means that if the string s is numeric, its parsed value is immediately assigned to the variable result.
In your code, you have the line double.TryParse(Console.ReadLine(), out pounds);
In this case, the input from the console is parsed to a double, and assigned to pounds if possible.

The user's input is assigned to the pounds variable within the TryParse() method.
The out modifier indicates that the argument is being passed by reference - which means that any changes to the argument (in this case, pounds) that occur within the method call will be applied to the actual variable.

It is get assigned when u take user's input using Console. ReadLine() method.
"I.e. double.TryParse(Console.ReadLine(), out pounds);"
User's input is extracted into pounds variable.

The other answers have explained your error. I thought I'd just show you how you should write your code to make it easier to understand:
public class PoundsToKilos
{
public static void Main()
{
double pounds = 0.0;
Console.Write("How many pounds? ");
if (double.TryParse(Console.ReadLine(), out pounds))
{
//`pounds` has been assigned a value
double kilograms = pounds * 0.453592;
Console.WriteLine("{0} pounds is equal to {1} kilograms", pounds, kilograms);
}
else
{
//`pounds` has NOT been assigned a value
Console.WriteLine("You didn't enter a valid number.");
}
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
}

Related

Why does this code not work when I try to convert it

This is only a small piece of the code I'm trying to make work. The original code I wrote works but I want to make sure when the user inputs a number it is in fact a number.
Console.WriteLine("Give the number of A");
A =Convert.ToDouble( Console.ReadLine());
if (char.IsNumber(Convert.ToDouble(A)) == correct)
{
Console.WriteLine(Convert.ToDouble( A * A));
}
else
{
Console.WriteLine("Incorrecrt input");
}
The Console.WriteLine(Convert.ToDouble(A*A)); I only wrote to see if that will work and it doesn't. After the user inputs only a number I must use it in another equation for a final answer. The user must input 3 numbers.
For me, you should check is the input is a number that you can convert to double before converting it.
Console.WriteLine("Give the number of A");
var a = Console.ReadLine();
double number;
if (double.TryParse(a, out number))//double.TryParse takes a parameter and tries to convert it to double. If the convertion is successfull, sets the out parameter as result and returns true. If not, returns false. And you can use with other types like int.Tryparse(param, out outParam);
{
A = number;
}
else
{
//Not a number, show a message etc...
{
If you break this down:
A =Convert.ToDouble( Console.ReadLine());
if (char.IsNumber(Convert.ToDouble(A)) == correct)
{
}
What you're basically doing is:
Double A = Convert.ToDouble(Console.ReadLine());
Double dbl = Convert.ToDouble(A);
Boolean bl = char.IsNumber(dbl);
if (bl== correct)
{
}
So there's multiple things wrong here.
Firstly, you're trying to convert the user input without any sort of guarantee of success, so if someone typed "A" instead of a number it will throw an exception.
You should use TryParse and then if it's a valid conversion proceed.
Secondly, you're checking if a Double is a char that can be converted to a number. Obviously not because it's already a Double.
Thirdly, you're checking if a Boolean is equal to some variable called correct (which you haven't provided the definition of) so it's not clear if this is a valid comparsion.
EDIT:
This is what I would do:
bool validInput = false;
do
{
Console.WriteLine("Give the number of A");
string userInput = Console.ReadLine();
if (double.TryParse(userInput, out double result))
{
validInput = true;
Console.WriteLine(result * result);
Console.ReadLine();
}
else
{
Console.WriteLine("Invalid input. Please type a number.");
}
} while (!validInput);

How could I convert a string variable to a double in C#

I am trying to convert a string variable to a double.
So far I have tried Convert.ToDouble()
string userAge;
Console.WriteLine("What is your age?");
Console.ReadLine();
Convert.ToDouble(userAge);
and when I tried to do operations on userAge it shows this error:
Program.cs(23,27): error CS0019: Operator '/' cannot be applied to operands of type 'string' and 'double' [/home/ccuser/workspace/csharp-working-with-numbers-arithmetic-operators-csharp/e3-workspace.csproj]
Program.cs(29,28): error CS0029: Cannot implicitly convert type 'string' to 'double' [/home/ccuser/workspace/csharp-working-with-numbers-arithmetic-operators-csharp/e3-workspace.csproj]
Program.cs(17,24): error CS0165: Use of unassigned local variable 'userAge' [/home/ccuser/workspace/csharp-working-with-numbers-arithmetic-operators-csharp/e3-workspace.csproj]
The build failed. Fix the build errors and run again.
Any suggestions?
To begin with, you need to assign the result of those method calls (to get the user input and then convert the string to a doulbe) to some variables so you can use them later in the code:
Console.WriteLine("What is your age?");
string input = Console.ReadLine();
double age = Convert.ToDouble(input);
But now we see there is a problem - if the user enters a non-numeric input, we'll get a FormatException.
Luckily there's a better method we can use for parsing strings to doubles: double.TryParse. This method takes in a string (the input), and an out parameter that it will set to the converted value on success (or the default value of 0 on failure). And the best thing is that it returns a bool that indicates if it was successful or not, so we can use it as a condition for a loop:
Console.Write("What is your age? ");
string userAge = Console.ReadLine();
double age;
while (!double.TryParse(userAge, out age))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
Console.Write("What is your age? ");
userAge = Console.ReadLine();
}
// Now 'age' is the converted value entered by the user
Now we have a solution that will loop until the user enters a valid number. But that's a fair amount of code. What if we have to get another number from them? Probably it would be better to extract this into a method that takes in a string (to use as a prompt) and which returns the strongly-typed double result:
public static double GetDoubleFromUser(string prompt)
{
bool isValid = true;
double result;
do
{
if (!isValid)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
}
else isValid = false;
Console.Write(prompt);
} while (!double.TryParse(Console.ReadLine(), out result));
return result;
}
Now our main code is much more simple:
double userAge = GetDoubleFromUser("What is your age? ");
double userWeight = GetDoubleFromUser("What is your weight? ");
Now, if we want to get a little fancier, we can include an optional 'validator' argument, which is a function that takes in a double and returns a bool, which we can use to further validate the result and force the user to enter a valid number.
For example, what if we want them to choose a number from 1 to 10? We don't want to have to setup a loop again for this further validation, so let's pass a Func<double, bool> to the method so it can do the validation for us!
For example:
public static double GetDoubleFromUser(string prompt, Func<double, bool> validator = null)
{
bool isValid = true;
double result;
do
{
if (!isValid)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
}
else isValid = false;
Console.Write(prompt);
} while (!double.TryParse(Console.ReadLine(), out result) &&
(validator == null || !validator.Invoke(result)));
return result;
}
Now we can pass in whatever validation we want to do on the input to the method! This would look something like the line of code below, and the method will not return until the user enters a valid number that's greater than or equal to 1 and less than or equal to 10:
double number = GetDoubleFromUser("Choose a number from 1 to 10: ",
x => x >= 1 && x <= 10);
You aren't assigning the result of your Convert call to a variable, you're just throwing it away. Convert doesn't alter the type of the existing variable (because, apart from other considerations, you simply can't do that in a strongly-typed language), instead it produces a new variable for you to use in your maths.
The error is, I presume without seeing the relevant code, because you tried to use userAge in your calculations which, as I've just explained, is still a string.
Also, to go back a step, you've never actually assigned the result of the ReadLine operation to the userAge variable in the first place.
This:
Console.WriteLine("What is your age?");
string userAge = Console.ReadLine();
double age = Convert.ToDouble(userAge);
would make more sense. And then use age in your calculations afterwards.

I need help instantiating multiple objects from a single method & class

C# HOMEWORK QUESTION: I am creating a console application that prompts for two integers, prompts for which math operation to perform, and returns the results. I was able to get it to work with my two operands hardcoded, and now I'm trying to instantiate two separate objects through user input instead of a hardcoded variable. I've stripped it down to the barebones code that I'm having issues with, and I suspect the problem has something to do with the way I'm creating two objects from the same method...but I'm not sure what.
Here's my main class...
public class MainModule
{
public static void Main(string[] args)
{
// get Operands
Console.WriteLine("You Will Be Entering Two Integers.\n");
//
MathUI myOperand1 = new MathUI();
int op1 = myOperand1.EnterInteger();
//
MathUI myOperand2 = new MathUI();
int op2 = myOperand2.EnterInteger();
Console.WriteLine("You chose {0} and {1}.", (int)op1, (int)op2);
Console.ReadLine();
}
}
...and the MathUI class that accepts inputs.
public class MathUI
{
public int EnterInteger()
{
Console.Write("Enter an integer: ");
int enteredInteger = Console.Read();
return (enteredInteger);
}
}
When I execute the program, I get a prompt for an integer. I enter, for instance, 3, here's my output.
You Will Be Entering Two Integers.
Enter an integer: 3
Enter an integer: You chose 51 and 13.
Math demo completed
Press <enter> to quit
When I press enter after entering the first integer, I automatically get a second integer; and when I try to output the integer values, they don't match my input.
What's going on here? Is there something wrong with the way that I'm instantiating MathUI and my two operands? Do I only need to instantiate one instance of MathUI then declare both variables under that one instance? I'm also not sure why the integer output does not match my input. All the variables are cast as int, so I should have int all the way through, right? I tried casting these as integers--(int)op1--just in case op1 was held in some internal form...but don't know what's going on there.
What am I missing?
you need to make the Console.Read a Console.ReadLine as readline is triggered by the return key.
public class MathUI
{
public int EnterInteger()
{
Console.Write("Enter an integer: ");
int enteredInteger = Convert.ToInt32(Console.ReadLine());
return (enteredInteger);
}
}
Problem is that you are using Console.Read method which returns a value after any key has been pressed. Also, result it returns is ASCII value of key pressed. In your case, you pressed 3 which has ordinal (ASCII) value of 51 in decimal system and then ENTER which has value 13. If you look at MSDN documentation, Console.Read returns an integer.
To read value user entered as a string, use Console.ReadLine method.
If you really need to read in key by key, you can use Convert.ToChar, and then ToString method to get entered key as string. Like so:
string key = Convert.ToChar(Console.ReadLine()).ToString();
Or you can use following code to read actual operand
int intOperand;
if (!int.TryParse(Console.ReadLine(), out intOperant))
Console.WriteLine("You pressed non-numeric key");
Use Console.ReadLine instead of Console.Read. With Console.Read, the return character is being passed as input to the second Read call.
Also note that the int that is returned by Console.Read is not parsing a numeric number, it is giving you the Unicode character value of the entered char. This is why you are getting the "wrong" numbers.
You need to use Console.ReadLine and parse the string result like so:
public class MathUI
{
public int EnterInteger()
{
Console.Write("Enter an integer: ");
int enteredInteger = int.Parse(Console.ReadLine());
return (enteredInteger);
}
}
A couple other notes for your consideration:
There's no need to cast the values in the Console.WriteLine call.
You can make the MathUI class and EnterInteger method static.

C# How to loop user input until the datatype of the input is correct?

How to make this piece of code loop asking for input from the user until int.TryParse()
is successful?
//setX
public void setX()
{
//take the input from the user
string temp;
int temp2;
System.Console.WriteLine("Enter a value for X:");
temp = System.Console.ReadLine();
if (int.TryParse(temp, out temp2))
x = temp2;
else
System.Console.WriteLine("You must enter an integer type value"); 'need to make it ask user for another input if first one was of invalid type'
}
Version of the code after the helpful answer:
//setX
public void setX()
{
//take the input from the user
string temp;
int temp2;
System.Console.WriteLine("Enter a value for X:");
temp = System.Console.ReadLine();
if (int.TryParse(temp, out temp2))
x = temp2;
else
{
Console.WriteLine("The value must be of integer type");
while (!int.TryParse(Console.ReadLine(), out temp2))
Console.WriteLine("The value must be of integer type");
x = temp2;
}
}
while (!int.TryParse(Console.ReadLine(), out mynum))
Console.WriteLine("Try again");
edit:
public void setX() {
Console.Write("Enter a value for X (int): ");
while (!int.TryParse(Console.ReadLine(), out x))
Console.Write("The value must be of integer type, try again: ");
}
Try this. I personally prefer to use while, but do .. while is also valid solution. The thing is that I don't really want to print error message before any input. However while has also problem with more complicated input that can't be pushed into one line. It really depends on what exactly you need. In some cases I'd even recommend to use goto even tho some people would probably track me down and slap me with a fish because of it.
Even though the question has been already marked as answered, do-while loops are much better for validating user input.
Notice your code:
Console.WriteLine("The value must be of integer type");
while (!int.TryParse(Console.ReadLine(), out temp2))
Console.WriteLine("The value must be of integer type");
You have the same code at top and bottom. This can be changed:
do {
Console.WriteLine("The value must be of integer type");
} while (!int.TryParse(Console.ReadLine(), out temp2));
This can help too
public int fun()
{
int Choice=0;
try
{
Choice = int.Parse(Console.ReadLine());
return choice;
}
catch (Exception)
{
return fun();
}
}
I've been wondering quite a lot, but I just figured it out!
int number;
bool check;
do
{
Console.WriteLine("Enter an integer:");
check = int.TryParse(Console.ReadLine(), out num1);
}
while (!check);
This code will loop until the user has entered an integer number. This way, the program doesn't simply report an error, but instead immediately allows the user to input again another, correct value.

Invalid token errors with enums

I'm having a little trouble with this code that I'm writing for a simple program. I get tons of errors saying "invalid token".
The program basically asks for 2 integers and sums them up, but the program needs to be called in another method.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AustinPDangeloJPA03
{
class Add
{
static void Main(string[] args)
{
double num1,
num2,
sum;
Console.Write("Enter the First integer: ");
num1 = int.Parse(Console.ReadLine());
//First Integer entered and storred
Console.Write("Enter the Second integer: ");
num2 = int.Parse(Console.ReadLine());
//Second Integer entered and storred
sum = Display(double a, double b);
//First and second numbers added together
Console.WriteLine(" {0} + {1} = {2} ",num1,num2,sum);
//displays the sum
//Instructs the user to press the Enter key to end the program
Console.WriteLine("Press the Enter key to terminate the program...");
Console.ReadLine();
}//Closes Main Method
static enum Display(a,b)
{
double c = a + b;
return c;
}//closes display method
}//Closes Class Add
}
This is not correct:
static enum Display(a,b)
{
double c = a + b;
return c;
}
The enum keyword is used to declare an enumeration. In order to define a method, you need a valid return type (such as int or double), and you need to provide the proper types for the individual arguments. You can optionally add static if you want it to be a static method, but that depends on its purpose.
I suspect you want to use something more like:
double Add(double a, double b)
{
// ...
If you then correct the line that called this method:
sum = Display(double a, double b);
This should compile and give you what you expect.
Your Display method is not declared correctly.
You need to declare a method that takes two numbers and returns a third number.
Consult your textbook and assignment for more information on how to declare a method and which types to use.
You're also not calling it correctly; method calls do not take types.
While it is not the source of your errors, it does indicate a misunderstanding of types:
double num1, num2,sum;
[...]
num1 = int.Parse(Console.ReadLine());
The first line declares some double variables.
The second line tries to parse int variables.
While the int will get auto-converted to a double, your code will be better if it is consistent with the use of types. You should switch to either int types, or to Double.Parse().
The enum keyword is for creating enumerations, for example:
public enum Color { Red, Green, Blue };
You have to specify a data type as return type for your Display method, and data types for the parameters:
static double Display(double a, double b) {
double c = a + b;
return c;
}
Also, you don't specify data types when you call the method, so change that to:
sum = Display(a, b);
Change this line to:
double sum = Display(num1, num2);
And change your Display method to be a method.
private static double Display(double a, double b)
{
double c = a + b;
return c;
}

Categories