Lesson 7 - Sanitizing user input in C# .NET
In the previous exercise, Solved tasks for C# .NET lesson 6, we've practiced our knowledge from previous lessons.
Lesson highlights
Are you looking for a quick reference on sanitizing user input in C# .NET instead of a thorough-full lesson? Here it is:
Using the TryParse()
method to handle
invalid user inputs and a while
loop to
keep the user entering:
Console.WriteLine("Enter a number:"); double a; while (!double.TryParse(Console.ReadLine(), out a)) Console.WriteLine("Invalid entry, please try again:");
Using ReadKey()
instead of
ReadLine()
when interested in one character only and the
default
switch
case
to handle
invalid inputs:
Console.WriteLine("Do you like C# .NET?:"); Console.WriteLine("1 - yes"); Console.WriteLine("2 - maybe"); Console.WriteLine("3 - no"); char option = Console.ReadKey().KeyChar; Console.WriteLine(); switch (option) { case '1': Console.WriteLine("Me too!"); break; case '2': Console.WriteLine("Come on, it's a nice language!"); break; case '3': Console.WriteLine("Maybe you should study harder"); break; default: Console.WriteLine("Invalid option!"); break; } Console.ReadKey();
Would you like to learn more? A complete lesson on this topic follows.
In the previous lesson, Solved tasks for C# .NET lesson 6, we introduced loops. Today's tutorial is going to be a little more relaxing because we're going to finish our calculator in C# .NET. We won't need it anymore after this, and it would be nice to finish it. You might already know that it lacks user input sanitation, which is what we're going to do today.
Let's bring up our calculator code:
Console.WriteLine("Welcome to our calculator"); string goOn = "yes"; while (goOn == "yes") { Console.WriteLine("Enter the first number:"); double a = double.Parse(Console.ReadLine()); Console.WriteLine("Enter the second number:"); double b = double.Parse(Console.ReadLine()); Console.WriteLine("Choose one of the following operations:"); Console.WriteLine("1 - addition"); Console.WriteLine("2 - subtraction"); Console.WriteLine("3 - multiplication"); Console.WriteLine("4 - division"); int option = int.Parse(Console.ReadLine()); double result = 0; switch (option) { case 1: result = a + b; break; case 2: result = a - b; break; case 3: result = a * b; break; case 4: result = a / b; break; } if ((option > 0) && (option < 5)) Console.WriteLine("Result: {0}", result); else Console.WriteLine("Invalid option"); Console.WriteLine("Would you like to make another calculation? [yes/no]"); goOn = Console.ReadLine(); } Console.WriteLine("Thank you for using our calculator. Press any key to end the program."); Console.ReadKey();
I had mentioned earlier that we should always sanitize user inputs. Let me tell you the secret to making successful and popular applications. It's very simple: You treat your users like total fools The sillier you expect the user to be, the more successful your applications will be. If the user enters "yes " (yes + space) rather than simply "yes", or he/she enters "Yes" (with a capital "Y"), the program would terminate. Which technically might not be due to user's silliness, more so because the user mistyped it. They could, however, enter something totally ridiculous, like: "maybe".
Either way, that's not the biggest problem in our program. When the user doesn't enter a number, but some nonsense instead, the whole program crashes with an error. Let's fix these two problems.
To validate the input before parsing it, we can use the
TryParse()
method instead of Parse()
. The method
returns true
/false
depending on whether the parsing
succeeded or not. If you're asking how we get the parsed value from the method,
the answer is that it'll be stored in a variable which we pass as the second
parameter. We must specify the out
modifier before
that parameter, but don't worry about all of that now, we'll explain it in later
courses. For now, just take it as a fact that the TryParse()
method
requires it. The value of the variable that we've passed as the second parameter
will be affected. Let's now look at the sanitized retrieving of the first
number, the parsing of the second number will be obviously analogical, so we can
just copy it. Ideally, we should have created a method for it, so we wouldn't
write the same code twice, but now is not the time to deal with all of that.
We'll learn how to declare methods in the object-oriented programming
course.
Console.WriteLine("Enter the first number:"); double a; while (!double.TryParse(Console.ReadLine(), out a)) Console.WriteLine("Invalid entry, please try again:");
There is nothing difficult about the code shown above. First, we ask the user
to enter the number and we declare the variable a
. Then we insert
TryParse()
in the condition of a while
loop and negate
this condition with the !
operator. So while the method returns
false
, the loop will keep going and asking the user to enter
another value. The entered text from the console will be parsed into a variable
and the method will return true
. If parsing fails, it will return
false
.
Now, let's look at the operational selection and continuation parts. We read
both inputs as string
s even though it's not quite appropriate to do
so. It makes sense to read the numbers as strings since they may be longer that
one character, so they must be submitted by pressing enter during the
selection of operations (1-4). Nonetheless, it's enough to read just a single
character and we don't need to submit it by pressing enter. We read a single
character using the Console.ReadKey()
method, which we've already
covered. To get the result as char
(character), we need to use the
KeyChar
property. In the switch
, we have to keep in
mind that we write char
values in apostrophes:
char option = Console.ReadKey().KeyChar; double result = 0; bool validOption = true; switch (option) { case '1': result = a + b; break; case '2': result = a - b; break; case '3': result = a * b; break; case '4': result = a / b; break; default: validOption = false; break; } if (validOption) Console.WriteLine("Result: {0}", result); else Console.WriteLine("Invalid option");
We store the entered character as a char
into the variable
option
. Because the range of characters can't be easily tested with
conditions as with integers with our current knowledge, but we'll check it in
another way. We prepare a bool
variable validOption
,
which is set to true
(which we assume to be correct). The
switch
remains the same, we only put numbers in apostrophes because
they're characters now. We add the default
case, which will set our
validOption
variable to false
in case that some
unspecified value was entered. Then, there is nothing easier than to test that
variable. Try it, the program is much more intuitive now.
Finally, we need to modify the continuing prompt. We'll enter the
Y/N char
acters and we'll make the input
case-insensitive and respond to invalid values. We'll use the
switch
again and change our variable, goOn
, to the
bool
datatype. It is unnecessary to describe this code, all that's
worth mentioning is the
Console.ReadKey().KeyChar.ToString().ToLower()
i.e. method
chaining, which reads a character from the console and returns it as a lowercase
string
.
Since this is a bigger piece of code, we'll use comments. We write them with double slashes. It is information for the programmer which the compiler ignores.
Console.WriteLine("Welcome to our calculator"); bool goOn = true; while (goOn) { // reading numbers Console.WriteLine("Enter the first number:"); double a; while (!double.TryParse(Console.ReadLine(), out a)) Console.WriteLine("Invalid entry, please try again:"); Console.WriteLine("Enter the second number:"); double b; while (!double.TryParse(Console.ReadLine(), out b)) Console.WriteLine("Invalid entry, please try again:"); // operation choice and calculation Console.WriteLine("Choose one of the following operations:"); Console.WriteLine("1 - addition"); Console.WriteLine("2 - subtraction"); Console.WriteLine("3 - multiplication"); Console.WriteLine("4 - division"); char option = Console.ReadKey().KeyChar; Console.WriteLine(); double result = 0; bool validOption = true; switch (option) { case '1': result = a + b; break; case '2': result = a - b; break; case '3': result = a * b; break; case '4': result = a / b; break; default: validOption = false; break; } if (validOption) Console.WriteLine("Result: {0}", result); else Console.WriteLine("Invalid option"); Console.WriteLine("Would you like to make another calculation? [y/n]"); // request to continue validOption = false; while (!validOption) { switch (Console.ReadKey().KeyChar.ToString().ToLower()) { case "y": goOn = true; validOption = true; break; case "n": goOn = false; validOption = true; break; default: Console.WriteLine("Invalid option, please enter y/n"); break; } } Console.WriteLine(); }
Console application
Welcome to our calculator
Enter the first number:
number
Invalid entry, please try again:
13
Enter the second number:
22
Choose one of the following operations:
1 - addition
2 - subtraction
3 - multiplication
4 - division
3
Result: 286
Would you like to make another calculation? [yes/no]
h
Invalid option, please enter y/n
Congratulations, you've just created your first foolproof program The code became a little more complicated, but it's worth it in the end. In the future, we may refactor it and split it up into separate methods. We'll say that our calculator is done for now (for this course, anyway). We could maybe add some more mathematical functions, but we'll get to that later in the course.
In the next lesson, Arrays in C# .NET, we'll dive into new constructs. Arrays and advanced work with strings await our arrival. Then, we'll finish the constructs in this course. We're approaching end
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 12x (143.02 kB)
Application includes source codes in language C#