Reading Input from the User
- Input and output in CLI
- Our programs use a command-line interface, where input and output come from text printed in a “terminal” or “console”
- We’ve already seen that
Console.WriteLineprints text from your program on the screen to provide output to the user - The equivalent method for reading input is
Console.ReadLine(), which waits for the user to type some text in the console and then returns it to your program - In general, the
Consoleclass represents the command-line interface
- Using
Console.ReadLine()-
Example usage:
using System; class PersonalizedWelcomeMessage { static void Main() { string firstName; Console.WriteLine("Enter your first name:"); firstName = Console.ReadLine(); Console.WriteLine($"Welcome, {firstName}!"); } }This program first declares a
stringvariable namedfirstName. On the second line, it usesConsole.WriteLineto display a message (instructions for the user). On the third line, it calls theConsole.ReadLine()method, and assigns its return value (result) to thefirstNamevariable. This means the program waits for the user to type some text and press “Enter”, and then stores that text infirstName. Finally, the program uses string interpolation inConsole.WriteLineto display a message including the contents of thefirstNamevariable. -
Console.ReadLineis the “inverse” ofConsole.WriteLine, and the way you use it is also the “inverse” -
While
Console.WriteLinetakes an argument, which is the text you want to display on the screen,Console.ReadLine()takes no arguments because it does not need any input from your program — it will always do the same thing -
Console.WriteLinehas no “return value” - it does not give any output back to your program, and the only effect of calling it is that text is displayed on the screen -
Console.ReadLine()does have a return value, specifically astring. This means you can use the result of this method to assign astringvariable, just like you can use the result of an arithmetic expression to assign a numeric variable. -
The
stringthatConsole.ReadLine()returns is one line of text typed in the console. When you call it, the computer will wait for the user to type some text and then press “Enter”, and everything the user typed before pressing “Enter” gets returned fromConsole.ReadLine()
-
Parsing user input
-
Console.ReadLine()always returns the same type of data, astring, regardless of what the user enters- If you ask the user to enter a number,
ReadLinewill output that number as astring - For example, if you ask the user to enter his/her age, and the user
enters 21,
Console.ReadLine()will return the string"21"
- If you ask the user to enter a number,
-
If we want to do any kind of arithmetic with a number provided by the user, we will need to convert that
stringto a numeric type likeintordouble. Remember that casting cannot be used to convert numeric data to or fromstringdata. -
When converting numeric data to
stringdata, we use string interpolation:int myAge = 29; //This does not work: //string strAge = (string) myAge; string strAge = $"{myAge}"; -
In the other direction, we use a method called
Parseto convertstrings to numbers:string strAge = "29"; //This does not work: //int myAge = (int) strAge; int myAge = int.Parse(strAge); -
The
int.Parsemethod takes astringas an argument, and returns anintcontaining the numeric value written in thatstring -
Each built-in numeric type has its own
Parsemethodint.Parse("42")returns the value 42long.Parse("42")returns the value42Ldouble.Parse("3.65")returns the value 3.65float.Parse("3.65")returns the value3.65fdecimal.Parse("3.65")returns the value3.65m
-
The Parse methods are useful for converting user input to useable data. For example, this is how to get the user’s age as an
int:Console.WriteLine("Enter your age:"); string ageString = Console.ReadLine(); int age = int.Parse(ageString);
More detail on the Parse methods
-
Console.WriteLineis a method that takes input from your program, in the form of an argument, but does not return any output. Meanwhile,Console.ReadLineis a method that does not have any arguments, but it returns output to your program (the user’s string). -
int.Parseis a method that both takes input (thestringargument) and returns output (the convertedintvalue) -
When executing a statement such as
int answer = int.Parse("42");the computer must evaluate the expression on the right side of the
=operator before it can do the assignment. This means it calls theint.Parsemethod with the string"42"as input. The method’s code then executes, converting"42"to an integer, and it returns a result, theintvalue42. This value can now be assigned to the variableanswer. -
Since the return value of a
Parsemethod is a numeric type, it can be used in arithmetic expressions just like a numeric-type variable or literal. For example, in this statement:double result = double.Parse("3.65") * 4;To evaluate the expression on the right side of the
=operator, the computer must first call the methoddouble.Parsewith the input"3.65". Then the method’s return value,3.65, is used the math operation as if it was written3.65 * 4. So the computer implicitly converts4to adoublevalue, performs the multiplication ondoubles, and gets the resulting value14.6, which it assigns to the variableresult. -
Another example of using the result of
Parseto do math:Console.WriteLine("Please enter the year."); string userInput = Console.ReadLine(); int curYear = int.Parse(userInput); Console.WriteLine($"Next year it will be {curYear + 1}");Note that in order to do arithmetic with the user’s input (i.e. add 1), it must be a numeric type (i.e.
int), not astring. This is why we often call aParsemethod on the data returned byConsole.ReadLine(). -
The previous example can be made shorter and simpler by combining the
ParseandReadLinemethods in one statement. Specifically, you can write:int curYear = int.Parse(Console.ReadLine());In this statement, the return value (output) of one method is used as the argument (input) to another method. When the computer executes the statement, it starts by evaluating the
int.Parse(...)method call, but it cannot actually execute theParsemethod yet because its argument is an expression, not a variable or value. In order to determine what value to send to theParsemethod as input, it must first evaluate theConsole.ReadLine()method call. Since this method has no arguments, the computer can immediately start executing it; theReadLinemethod waits for the user to type a line of text, then returns that text as astringvalue. This return value can now be used as the argument toint.Parse, and the computer starts executingint.Parsewith the user-provided string as input. When theParsemethod returns anintvalue, this value becomes the value of the entire expressionint.Parse(Console.ReadLine()), and the computer assigns it to the variablecurYear. -
Notice that by placing the call to
ReadLineinside the argument toParse, we have eliminated the variableuserInputentirely. Thestringreturned byReadLinedoes not need to be stored anywhere (i.e. in a variable); it only needs to exist long enough to be sent to theParsemethod as input.
Correct input formatting
- The Parse methods assume that the string they are given as an argument (i.e. the user input) actually contains a valid number. But the user may not follow directions, and invalid input can cause a variety of errors.
- If the string does not contain a number at all —
e.g.
int badIdea = int.Parse("Hello");— the program will fail with the errorSystem.FormatException - If the string contains a number with a decimal point, but the
Parsemethod is for an integer datatype, the program will also fail withSystem.FormatException. For example,int fromFraction = int.Parse("52.5");will cause this error. This will happen even if the number in the string ends in “.0” (meaning it has no fractional part), such asint wholeNumber = int.Parse("45.0");. - If the string has extraneous text before or after the number, such as
"$18.95"or1999!, the program will fail with the errorSystem.FormatException - If the string contains a number that cannot fit in the desired
datatype (due to overflow or underflow), the behavior depends on the
datatype:
- For the integer types (
intandlong), the program will fail with the errorSystem.OverflowException. For example,int.Parse("3000000000")will cause this error because 3000000000 is larger than (the maximum value anintcan store). - For the floating-point types (
floatanddouble), no error will be produced. Instead, the result will be the same as if an overflow or underflow had occurred during normal program execution: an overflow will produce the valueInfinity, and an underflow will produce the value0. For example,float tooSmall = float.Parse("1.5e-55");will assigntooSmallthe value 0, whiledouble tooBig = double.Parse("1.8e310");will assigntooBigthe valuedouble.Infinity.
- For the integer types (
- Acceptable string formats vary slightly between the numeric types, due
to the different ranges of values they can contain
int.Parseandlong.Parsewill accept strings in the format([ws])([sign])[digits]([ws]), where[ws]represents empty spaces and groups in parentheses are optional. This means that a string with leading or trailing spaces will not cause an error, unlike a string with other extraneous text around the number.decimal.Parsewill accept strings in the format([ws])([sign])([digits],)[digits](.[digits])([ws]). Note that you can optionally include commas between groups of digits, and the decimal point is also optional. This means a string like"18,999"is valid fordecimal.Parsebut not forint.Parse.float.Parseanddouble.Parsewill accept strings in the format([ws])([sign])([digits],)[digits](.[digits])(e[sign][digits])([ws]). As withdecimal, you can include commas between groups of digits. In addition, you can write the string in scientific notation with the letter “e” or “E” followed by an exponent, such as"-9.44e15".
Output with Variables
Converting from numbers to strings
-
As we saw in a previous lecture (Datatypes and Variables), the
Console.WriteLinemethod needs astringas its argument -
If the variable you want to display is not a
string, you might think you could cast it to astring, but that will not work — there is no explicit conversion fromstringto numeric types-
This code:
double fraction = (double) 47 / 6; string text = (string) fraction;will produce a compile error
-
-
You can convert numeric data to a
stringusing string interpolation, which we’ve used before inConsole.WriteLinestatements:int x = 47, y = 6; double fraction = (double) x / y; string text = $"{x} divided by {y} is {fraction}";After executing this code,
textwill contain “47 divided by 6 is 7.8333333” -
String interpolation can convert any expression to a
string, not just a single variable. For example, you can write:Console.WriteLine($"{x} divided by {y} is {(double) x / y}"); Console.WriteLine($"{x} plus 7 is {x + 7}");This will display the following output:
47 divided by 6 is 7.8333333 47 plus 7 is 54Note that writing a math expression inside a string interpolation statement does not change the values of any variables. After executing this code,
xis still 47, andyis still 6.
The ToString() method
-
String interpolation does not “magically know” how to convert numbers to strings — it delegates the task to the numbers themselves
-
This works because all data types in C# are objects, even the built-in ones like
intanddouble- Since they are objects, they can have methods
-
All objects in C# are guaranteed to have a method named
ToString(), whose return value (result) is astring -
Meaning of
ToString()method: “Convert this object to astring, and return thatstring” -
This means you can call the
ToString()method on any variable to convert it to astring, like this:int num = 42; double fraction = 33.5; string intText = num.ToString(); string fracText = fraction.ToString();After executing this code,
intTextwill contain the string “42”, andfracTextwill contain the string “33.5” -
String interpolation calls
ToString()on each variable or expression within braces, asking it to convert itself to a string-
In other words, these three statements are all the same:
Console.WriteLine($"num is {num}"); Console.WriteLine($"num is {intText}"); Console.WriteLine($"num is {num.ToString()}");Putting
numwithin the braces is the same as callingToString()on it.
-
String Concatenation
- Now that we’ve seen
ToString(), we can introduce another operator: the concatenation operator - Concatenation basics
-
Remember, the
+operator is defined separately for each data type. The “double + double” operator is different from the “int + int” operator. -
If the operand types are
string(i.e.string + string), the+operator performs concatenation, not addition -
You can concatenate
stringliterals orstringvariables:string greeting = "Hi there, " + "John"; string name = "Paul"; string greeting2 = "Hi there, " + name;After executing this code,
greetingwill contain “Hi there, John” andgreeting2will contain “Hi there, Paul”
-
- Concatenation with mixed types
-
Just like with the other operators, both operands (both sides of the
+) must be the same type -
If one operand is a
stringand the other is not astring, theToString()method will automatically be called to convert it to astring -
Example: In this code:
int bananas = 42; string text = "Bananas: " + bananas;The
+operator has astringoperand and anintoperand, so theintwill be converted to astring. This means the computer will callbananas.ToString(), which returns the string “42”. Then thestring + stringoperator is called with the operands “Bananas:” and “42”, which concatenates them into “Bananas: 42”.
-
Output with concatenation
-
We now have two different ways to construct a string for
Console.WriteLine: Interpolation and concatenation -
Concatenating a string with a variable will automatically call its
ToString()method, just like interpolation will. These twoWriteLinecalls are equivalent:int num = 42; Console.WriteLine($"num is {num}"); Console.WriteLine("num is " + num); -
It’s usually easier to use interpolation, since when you have many variables the
+signs start to add up. Compare the length of these two equivalent lines of code:Console.WriteLine($"The variables are {a}, {b}, {c}, {d}, and {e}"); Console.WriteLine("The variables are " + a + ", " + b + ", " + c + ", " + d + ", and " + e); -
Be careful when using concatenation with numeric variables: the meaning of
+depends on the types of its two operands-
If both operands are numbers, the
+operator does addition -
If both operands are strings, the
+operator does concatenation -
If one argument is a string, the other argument will be converted to a string using
ToString() -
Expressions in C# are always evaluated left-to-right, just like arithmetic
-
Therefore, in this code:
int var1 = 6, var2 = 7; Console.WriteLine(var1 + var2 + " is the result"); Console.WriteLine("The result is " + var1 + var2);The first
WriteLinewill display “13 is the result”, becausevar1andvar2are bothints, so the first+operator performs addition on twoints (the resulting number,13, is then converted to astringfor the second+operator). However, the secondWriteLinewill display “The result is 67”, because both+operators perform concatenation: The first one concatenates a string withvar1to produce a string, and then the second one concatenates this string withvar2 -
If you want to combine addition and concatenation in the same line of code, use parentheses to make the order and grouping of operations explicit. For example:
int var1 = 6, var2 = 7; Console.WriteLine((var1 + var2) + " is the result"); Console.WriteLine("The result is " + (var1 + var2));In this code, the parentheses ensure that
var1 + var2is always interpreted as addition.
-