๐ Lesson 2.3: Console Input and Output
So far your programs have only talked to the user. Now they'll listen. You'll read what someone types, turn that text into numbers, and format your output cleanly.
๐ฏ Learning Objectives
By the end of this lesson, you will be able to:
- Read a line of user input with
Console.ReadLine() - Format output cleanly with string interpolation (
$"...") - Convert input text into numbers with
int.Parseand friends - Handle bad input safely using
TryParse - Write a complete interactive program
Estimated Time: 45 minutes
Project: Build an interactive tip calculator that reads numbers from the user.
In This Lesson
Output, Revisited
You already know two output methods from Module 1:
Console.WriteLine(...)โ print text, then move to a new line.Console.Write(...)โ print text and stay on the same line.
Console.Write is perfect for prompts, because it keeps the cursor right after your question so the user's typing appears on the same line:
Console.Write("What is your name? ");
// The cursor stays here โ user types on the same line
Communication with a console program is a simple back-and-forth loop:
(Write)"] --> B["User types
+ Enter"] B --> C["Program reads
(ReadLine)"] C --> D["Program responds
(WriteLine)"] style A fill:#eff6ff,stroke:#3b82f6,stroke-width:2px style D fill:#e8f5e9,stroke:#4CAF50,stroke-width:2px
String Interpolation
In Lesson 2.1 we joined text and values with +. That works, but it gets clumsy fast. String interpolation is a much cleaner way to drop variables directly inside a string.
Put a $ before the opening quote, then wrap any variable or expression in { } (curly braces) inside the string:
string name = "Ada";
int age = 30;
// The old way, with + concatenation:
Console.WriteLine("Hello, " + name + "! You are " + age + ".");
// The clean way, with string interpolation:
Console.WriteLine($"Hello, {name}! You are {age}.");
Output (both lines are identical):
Hello, Ada! You are 30.
Hello, Ada! You are 30.
You can even put whole expressions inside the braces โ they're evaluated and inserted:
int a = 7, b = 5;
Console.WriteLine($"{a} + {b} = {a + b}"); // 7 + 5 = 12
โ Prefer interpolation
String interpolation ($"...") is easier to read and less error-prone than long chains of +. We'll use it for the rest of the course.
๐ก Formatting numbers
You can format a value right inside the braces. For example, {price:C} formats a number as currency and {ratio:F2} shows 2 decimal places:
decimal price = 19.5m;
Console.WriteLine($"Total: {price:C}"); // Total: $19.50 (depends on region)
double ratio = 2.0 / 3.0;
Console.WriteLine($"Ratio: {ratio:F2}"); // Ratio: 0.67
Reading Input
To read what the user types, use Console.ReadLine(). It waits for the user to type a line and press Enter, then hands you back what they typed:
Console.Write("What is your name? ");
string name = Console.ReadLine();
Console.WriteLine($"Nice to meet you, {name}!");
Sample run (user types "Ada"):
What is your name? Ada
Nice to meet you, Ada!
โ ๏ธ ReadLine always gives you a string
This is the single most important thing to remember in this lesson: everything the user types comes back as text (a string) โ even if they type 42. To do math with it, you must first convert that text into a number, which is our next topic.
Text to Numbers: Parsing
Converting text like "42" into the number 42 is called parsing. Each numeric type has a .Parse helper:
| To get aโฆ | Use |
|---|---|
int | int.Parse(text) |
double | double.Parse(text) |
decimal | decimal.Parse(text) |
Console.Write("Enter your age: ");
string input = Console.ReadLine();
int age = int.Parse(input); // "30" โ 30
int nextYear = age + 1;
Console.WriteLine($"Next year you'll be {nextYear}.");
You'll often combine the reading and parsing into one line, which is a very common pattern:
Console.Write("Enter your age: ");
int age = int.Parse(Console.ReadLine());
Console.WriteLine($"Next year you'll be {age + 1}.");
โ ๏ธ Parsing can crash
If the user types something that isn't a valid number โ like hello โ then int.Parse can't do its job and the program crashes with an error (a "FormatException"). That's obviously not great. The next section shows the safe way to handle this.
Handling Bad Input Safely
Real users make typos. Instead of crashing, we can try to parse and check whether it worked. That's what int.TryParse does. It returns a bool โ true if the text was a valid number, false if not โ and puts the parsed number into a variable for you:
Console.Write("Enter your age: ");
string input = Console.ReadLine();
if (int.TryParse(input, out int age))
{
Console.WriteLine($"Next year you'll be {age + 1}.");
}
else
{
Console.WriteLine("That wasn't a valid whole number.");
}
๐ก Reading the TryParse pattern
int.TryParse(input, out int age)attempts the conversion.- The
out int agepart declares the variableageand fills it in if parsing succeeds. - The whole call is
trueorfalse, so we use it directly in anif(which you'll study in the very next lesson).
Don't worry about mastering if or out yet โ just recognize the shape. TryParse is the safe, professional way to handle user input.
โ Parse vs. TryParse
Use int.Parse when you're certain the text is a valid number (e.g. a value you created). Use int.TryParse whenever the text comes from a user or another unpredictable source โ it never crashes on bad input.
A Complete Interactive Program
Let's tie it all together: prompts, reading, parsing, math, and interpolation in one program. Create a project (dotnet new console -o Greeter) and try this:
Console.Write("What is your name? ");
string name = Console.ReadLine();
Console.Write("What year were you born? ");
int birthYear = int.Parse(Console.ReadLine());
int approxAge = 2026 - birthYear;
Console.WriteLine($"Hello, {name}!");
Console.WriteLine($"You are about {approxAge} years old.");
Sample run:
What is your name? Ada
What year were you born? 1996
Hello, Ada!
You are about 30 years old.
This is a real, interactive program โ it responds differently depending on what the user types. Everything from Module 2 is working together here: variables, types, an arithmetic expression, input, parsing, and interpolated output.
Exercise & Quiz
๐๏ธ Exercise: Tip Calculator
Objective: Read numbers from the user and compute a result with clean, formatted output.
Instructions:
- Create a new project called
TipCalc. - Prompt for the bill amount and read it as a
decimal(usedecimal.Parse). - Prompt for the tip percentage (a whole number like
20) and read it as anint. - Calculate the tip and the total. (Tip = bill ร percentage รท 100.)
- Print the tip and total using string interpolation, formatted as currency with
{value:C}. - Bonus: Use
decimal.TryParseso bad input doesn't crash the program.
Starter Code:
Console.Write("Enter the bill amount: ");
decimal bill = decimal.Parse(Console.ReadLine());
Console.Write("Enter the tip percentage: ");
int tipPercent = int.Parse(Console.ReadLine());
// TODO: calculate tip and total
// TODO: print them formatted as currency ({value:C})
๐ก Hint
To keep money math exact, convert the percentage to a decimal fraction: decimal tip = bill * tipPercent / 100m; (the 100m keeps it in decimal). The total is bill + tip. Format with $"{tip:C}".
โ Solution
Console.Write("Enter the bill amount: ");
decimal bill = decimal.Parse(Console.ReadLine());
Console.Write("Enter the tip percentage: ");
int tipPercent = int.Parse(Console.ReadLine());
decimal tip = bill * tipPercent / 100m;
decimal total = bill + tip;
Console.WriteLine($"Tip: {tip:C}");
Console.WriteLine($"Total: {total:C}");
Sample run:
Enter the bill amount: 50
Enter the tip percentage: 20
Tip: $10.00
Total: $60.00
Bonus (safe version):
Console.Write("Enter the bill amount: ");
if (decimal.TryParse(Console.ReadLine(), out decimal bill))
{
Console.Write("Enter the tip percentage: ");
if (int.TryParse(Console.ReadLine(), out int tipPercent))
{
decimal tip = bill * tipPercent / 100m;
Console.WriteLine($"Tip: {tip:C}");
Console.WriteLine($"Total: {bill + tip:C}");
}
else
{
Console.WriteLine("The tip percentage must be a whole number.");
}
}
else
{
Console.WriteLine("The bill amount must be a number.");
}
๐ฏ Quick Quiz
Question 1: What type does Console.ReadLine() return?
Question 2: Which line correctly uses string interpolation?
Question 3: Why prefer int.TryParse over int.Parse for user input?
Summary
๐ Key Takeaways
Console.Writeis ideal for prompts (keeps the cursor on the same line);Console.WriteLineadds a new line.- String interpolation
$"...{variable}..."is the clean way to build output; you can format values like{price:C}. Console.ReadLine()reads a line of input and always returns astring.- Parse text into numbers with
int.Parse,double.Parse,decimal.Parse. - Use
TryParsefor user input โ it safely reports success instead of crashing on bad input.
๐ Additional Resources
- Console.ReadLine โ API reference
- String interpolation โ reference
- Parsing numeric strings โ Microsoft Docs
๐ What's Next?
That completes Module 2 โ your programs can now store data, calculate, and interact with the user! In Module 3, we teach programs to make choices. First up: Lesson 3.1: Making Decisions with if and switch, where you saw a preview of if in the TryParse pattern above.
๐ Module 2 complete!
Your programs are now interactive. That's a huge milestone โ take a moment to appreciate it, then let's teach them to make decisions.