Getting user input (C#)

Cookieman

BSOD Kernel Dump Senior Analyst
Joined
Jun 21, 2012
Posts
124
Location
Lincoln (UK)
Hi all

Finally managing to grab a bit of time to learn a little bit about programming, after swaying to and fro I decided to learn c# . I have a simple program I am trying to create for work which involves user input. What I need to do is ask for user input for a variable, which in this case I have called nom

I know that in C++ I can grab the input I need by simply using the following:

Code:
float nom;
cout << "Please Enter The Product Nominal: " >> cin nom;

What I want to do is to convert this to c#. So far I have this.. (and failed miserably!)

Code:
float nom;
Console.WriteLine("Enter Product Nominal");
nom = Console.ReadLine();

From what I can tell it is getting the input as a string and would need converting to float but is there an easier way?
 
Hello :)

Well done with the excellent progress you have made so far.

You have pretty much got it worked out. You can only really read the input as a string, and since you want it as a float, you have to do the conversion.

Fortunately, the conversion is fairly easy.

Change:

Code:
nom = Console.ReadLine();

to:

Code:
nom = Convert.ToSingle(Console.ReadLine());

However, if your user inputs something which is not a number (such as "abc") your program will crash. (This is part of the reason why these conversions are not automatic: some checks must be done to make sure it is a proper number as a user can enter data into a string which cannot be converted to a number, so these conversion methods are needed.) To prevent this, you must catch some exceptions.

So use this instead:

Code:
try 
{
    nom = Convert.ToSingle(Console.ReadLine()); 
}   
catch (FormatException)
{
      Console.WriteLine("Unable to convert inputted data to a float.");
}               
catch (OverflowException) 
{
      Console.WriteLine("The number specified is outside the range of a float.");
}

In general, convertions are done with

Code:
Convert.To[I]Whatever[/I](input);

or
Code:
input.ToString()

(the latter only works reliably for .ToString(), but occasionally you can use it for other data types, but it usually doesn't work on arrays though.)

Float is unusual in that it is called a single behind the scenes, hence .ToSingle(). Just something to learn and get over. It is much more logical for almost all other data types which are as you expect them to be, in general.

Good luck!

Richard
 
Last edited:
Thanks for the input Richard, time to get some more caffeine brewing.... :)

Quick question on this point:

Code:
Convert.To[I]Whatever[/I](input);

So I can also use it as in the following statements...

Code:
Convert.ToShort[COLOR=#3E3E3E](Console.ReadLine());[/COLOR]
Code:
Convert.ToDouble[COLOR=#3E3E3E](Console.ReadLine());[/COLOR]

I have also just come across another example of a workaround using this method here >> C# Tutorial

Code:
[COLOR=#000000]number2 [/COLOR][COLOR=#000000]=[/COLOR][COLOR=#0000FF]int[/COLOR][COLOR=#000000].Parse(Console.ReadLine());[/COLOR]

Is there a good or bad way of practice, or is it simply down to the person writing the program?
 
Quick question on this point:

Code:
Convert.To[I]Whatever[/I](input);

So I can also use it as in the following statements...

Code:
Convert.ToShort[COLOR=#3e3e3e](Console.ReadLine());[/COLOR]
Code:
Convert.ToDouble[COLOR=#3e3e3e](Console.ReadLine());[/COLOR]

Exactly, you can convert it to whatever you like in that way.

I have also just come across another example of a workaround using this method here >> C# Tutorial

Code:
[COLOR=#000000]number2 [/COLOR][COLOR=#000000]=[/COLOR][COLOR=#0000ff]int[/COLOR][COLOR=#000000].Parse(Console.ReadLine());[/COLOR]

Is there a good or bad way of practice, or is it simply down to the person writing the program?

Both work fine. In actual fact, float.Parse(input); may actually have been slightly better here, although the difference is small. Basically, here are the differences:

Firstly, .Parse() and .TryParse() only accept strings as input, whereas Convert.ToWhatever will take almost anything (technically, any class which implements the interface IConvertible, but you don't need to worry about that for now). Therefore, if you are trying to convert anything which isn't a string (maybe from one number format to another which can't be casted, then you must use Convert.ToWhatever, as you have no choice in the matter). Here, however, you are using a string, so there is still a choice.

There is also a change in functionality. If input is null, .Parse() will throw an ArgumentNullException, whereas Convert.To...() will return 0. So you need to make a choice there if this is important to you.

However, there is another consideration with .Parse(). Handing exceptions with try{} catch{} is incredibly slow. When you ask a user for input, it is quite likely that they won't type a pure integer. Thus, first checking with the much faster .TryParse(); may be quicker in the long run, as it bypasses the slow exception handling. But then again, both would be done in less than human reaction time, and you are not running thousands in order to notice a difference.

Therefore, .TryParse() first may be faster. If, however, you don't envisage any exceptions happening often (maybe another part of your program is providing the data, and you can't see why it wouldn't provide a perfect integer), then bypassing .TryParse() and leaving it to exceptions will be faster.

Convert.To...() will be the slowest, as it has to do type checking and null string checking, and then it just calls int/float.Parse() under the hood for a string. But it is convenient.

Probably just ignore all this and decide based on null string handling.

Another quick tip, it is often a good idea to .Trim() strings to remove any whitespace. This is not so important in console application input reading, but elsewhere it is important. I am sure you already know, but just in case:

Code:
Console.ReadLine().Trim();

Richard
 
Hello :)

Well done with the excellent progress you have made so far.

You have pretty much got it worked out. You can only really read the input as a string, and since you want it as a float, you have to do the conversion.

Fortunately, the conversion is fairly easy.

Change:

Code:
nom = Console.ReadLine();

to:

Code:
nom = Convert.ToSingle(Console.ReadLine());

However, if your user inputs something which is not a number (such as "abc") your program will crash. (This is part of the reason why these conversions are not automatic: some checks must be done to make sure it is a proper number as a user can enter data into a string which cannot be converted to a number, so these conversion methods are needed.) To prevent this, you must catch some exceptions.

So use this instead:

Code:
try 
{
    nom = Convert.ToSingle(Console.ReadLine()); 
}   
catch (FormatException)
{
      Console.WriteLine("Unable to convert inputted data to a float.");
}               
catch (OverflowException) 
{
      Console.WriteLine("The number specified is outside the range of a float.");
}

In general, convertions are done with

Code:
Convert.To[I]Whatever[/I](input);

or
Code:
input.ToString()

(the latter only works reliably for .ToString(), but occasionally you can use it for other data types, but it usually doesn't work on arrays though.)

Float is unusual in that it is called a single behind the scenes, hence .ToSingle(). Just something to learn and get over. It is much more logical for almost all other data types which are as you expect them to be, in general.

Good luck!

Richard

Yikes, don't catch all exceptions when it can be avoided though if you're only there to prevent them. This reduces the functionality of the program itself, and is bad habit to Try Catch everything. TryParse() methods were specifically created to increase the optimization of the regular type Parse methods when the input is unknown and variable from parsable and non-parsable values.

I'd highly suggest doing something like this:
Code:
float nom;
Console.WriteLine("Enter Product Nominal:");
string input = Console.ReadLine();
if (float.TryParse(input, out nom))
{
	//Valid input
}
else
{
	//Invalid input
}

If it's a valid input, nom will then hold the parsed value (in System.Type float) for you to use.

As an example, furthermore, you can also validate the numeric value type after the fact.

Code:
float nom;
string input = "9";
if (float.TryParse(input, out nom) && nom > 10)
{
	Console.WriteLine("Valid: " + nom.ToString());
}
else
{
	Console.WriteLine("Invalid: " + input);
}

In this case, nom (the out param) is evaluated after the TryParse method is called. This is important because nom doesn't get assigned to anything other than the default of the float type, until that TryParse assigns it a parsed value based on the input, but will not be evaluated if the first conditional returns false. So we can avoid several issues here.

1) The input being a non-numeric representable type, in terms of a float (single floating point) value.
2) If the string representative value cast to a float can be made, we can evaluate that numeric value type (of type float) through mathematical logic, to further evaluate the input, before we even do anything inside of this if statement if returned as true.

To test: Try this snippet with these different variations of input strings:

1) "9" (parsable float value, not greater than 10, returns false)
2) "10" (parsable float value, still not greater than 10, returns false)
3) "11" (parsable float value, greater than 10, returns true)
4) "150.0" (parsable float value, greater than 10, returns true)
5) "FF" (non-parsable float value, greater than 10 in hexadecimal which is not recognized here though because it can't be inferred as any numeric value, returns false)
etc...

See what the output is, and try to figure out why you see what you see.

To your benefit TryParse here was specifically optimized for string input as well. Convert methods are not, and before we can evaluate the input, before seeing if it's parsable, an exception is also thrown, which reduces the performance of an application in itself. Exception throwing is only needed under certain circumstances, and if you're not going to do anything with the exception, then why throw it?
 
Last edited:
Thanks for the input from you both.

Some of it a little over my head at the moment I must admit, but I can roughly see what you are saying. I guess things will fall into shape better as I move along the learning curve!

I will also have many more questions to come too....

:rofl12:
 

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top