C# Programming Tutorial 0/45 lessons ~6 min read Lesson 6

    User Input & Output

    Console I/O is the fastest way to prototype logic; production systems use structured logging, HTTP, and message buses.

    Course progress0%
    Focus
    10 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Console I/O is the fastest way to prototype logic; production systems use structured logging, HTTP, and message buses. Still, mastering Console, TextReader/Writer, and culture-aware formatting builds foundations for CLI tools and interview stdin/stdout problems.

    Enterprise apps prefer ILogger over Console.WriteLine, but parsing user input with TryParse, validating ranges, and formatting currency with CultureInfo appear daily in banking terminals and healthcare kiosks.

    This lesson covers ReadLine, WriteLine, string interpolation, composite formatting, and safe parsing patterns that prevent unhandled FormatException in production.

    The story

    A bank teller kiosk asks customers to type a deposit amount on a touchscreen. The app reads input from the console (or a simulated input stream in tests), validates that the value is a positive number, and prints a formatted confirmation like Accepted deposit: $250.00.

    Separating input and output into TextReader and TextWriter lets QA automate the same logic without a human at the keyboard — a pattern used daily in enterprise testing.

    Understanding the topic

    Key concepts

    • Console.In/Out/Error map to standard streams for CLI integration.
    • ReadLine returns string? — null on EOF; always validate.
    • int.TryParse, decimal.TryParse avoid exception-based control flow.
    • String interpolation ($"value {expr}") calls ToString on expressions.
    • CultureInfo.InvariantCulture for machine-readable logs; CurrentCulture for UI.
    • StringBuilder for efficient large string assembly.
    text
    sequenceDiagram
    User->>Console: ReadLine()
    Console->>App: string input
    App->>App: Parse & Validate
    App->>Console: WriteLine(result)

    Step-by-step explanation

    1. Prompt user with Console.Write (no newline) or WriteLine.
    2. ReadLine blocks until Enter; trim whitespace before parse.
    3. TryParse returns bool and out parameter with parsed value.
    4. Format numbers: value.ToString('C', culture) for currency.
    5. Redirect input/output in tests via StringReader/StringWriter.
    6. Async console APIs available but rarely used — prefer async streams for files/network.

    Practical code example

    Interactive deposit CLI with TryParse and invariant culture logging:

    csharp
    namespace TechLearningPro.IO;
    public static class DepositCli
    {
    public static void Run(TextReader input, TextWriter output)
    {
    output.WriteLine("Enter deposit amount (USD):");
    var line = input.ReadLine();
    if (!decimal.TryParse(line, NumberStyles.Number, CultureInfo.InvariantCulture, out var amount)
    || amount <= 0)
    {
    output.WriteLine("Invalid amount. Use format: 123.45");
    return;
    }
    output.WriteLine(CultureInfo.InvariantCulture,
    quot;Accepted deposit: {amount:C}");
    }
    }

    Output

    Enter deposit amount (USD):
    Accepted deposit: $250.00

    Line-by-line code explanation

    • Run(TextReader input, TextWriter output) accepts abstract streams so unit tests can inject fake readers/writers.
    • output.WriteLine("Enter deposit amount...") prompts the user before reading input.
    • input.ReadLine() reads one line of text typed by the user (or supplied by a test).
    • decimal.TryParse(line, NumberStyles.Number, CultureInfo.InvariantCulture, out var amount) safely parses numbers independent of regional settings.
    • || amount <= 0 rejects zero and negative deposits in the same condition.
    • output.WriteLine("Invalid amount...") gives actionable feedback when parsing fails.
    • return exits early without processing invalid input further.
    • output.WriteLine(..., $"Accepted deposit: {amount:C}") formats the accepted amount as currency using invariant culture.

    Key takeaway: Inject TextReader/TextWriter for unit testing without real console. InvariantCulture keeps logs consistent across regions.

    Real-world use

    Where you'll use this in production

    • DevOps CLI tools accepting parameters interactively or from pipes.
    • Healthcare kiosk weight entry with validation and localized display.
    • Coding interview stdin/stdout judge problems.
    • Migration scripts prompting for connection string confirmation.

    Best practices

    • Always use TryParse for user/external input.
    • Separate display culture from storage format (ISO 8601, invariant decimals).
    • Write errors to Console.Error or ILogger LogError.
    • Avoid ReadLine in ASP.NET — use model binding instead.
    • Use StringBuilder for >3 concatenations in loops.

    Common mistakes

    • Parse without TryParse — crashes on bad input.
    • Concatenating culture-specific strings in persisted logs.
    • Assuming ReadLine never returns null.
    • Using + in tight loops for string building.

    Advanced interview questions

    Q1BeginnerHow read user input safely?
    Console.ReadLine then TryParse with culture; validate range.
    Q2BeginnerPurpose of StringBuilder?
    Mutable buffer avoiding repeated string allocations during concatenation.
    Q3IntermediateInvariantCulture vs CurrentCulture?
    Invariant for storage/logs; CurrentCulture for user-facing formatted output.
    Q4IntermediateTest console apps without manual typing?
    Inject TextReader/StringReader with predetermined input strings.
    Q5AdvancedDesign a CLI that works in CI (non-interactive) and locally (interactive).
    Detect Console.IsInputRedirected; read args/env when redirected, prompt when interactive; consistent exit codes.

    Summary

    Console I/O uses standard streams; validate all external input. TryParse and culture-aware formatting prevent runtime format errors. Inject abstractions for testable CLI logic. Production web apps use model binding and ILogger instead of Console. Next: if/else and boolean decision logic.

    Ready to mark this lesson complete?Track your journey across the entire course.