How to read user input in CLI

Cli
Use the `std::io` module to read from `stdin` by creating a `String` buffer and calling `read_line()` on `std::io::stdin()`.

Use the std::io module to read from stdin by creating a String buffer and calling read_line() on std::io::stdin(). You must trim the trailing newline character and handle the Result to manage potential I/O errors gracefully.

Here is a standard pattern using the ? operator for error propagation:

use std::io::{self, Write};

fn main() -> io::Result<()> {
    let mut input = String::new();

    print!("Enter your name: ");
    // Flush stdout to ensure the prompt appears before reading
    io::stdout().flush()?;

    io::stdin().read_line(&mut input)?;

    // Trim whitespace (including the newline) from the input
    let name = input.trim();
    println!("Hello, {}!", name);

    Ok(())
}

For more complex CLI applications, consider using the dialoguer or clap crates. dialoguer provides a higher-level API for interactive prompts with built-in support for validation and hidden input (like passwords), while clap is ideal for parsing command-line arguments and flags.

Here is an example using dialoguer for a password prompt:

use dialoguer::Password;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let password = Password::new()
        .with_prompt("Enter password")
        .interact()?;

    println!("Password length: {}", password.len());
    Ok(())
}

Remember that read_line reads until a newline character is encountered, which is why trim() is essential to remove the \n (or \r\n on Windows) from the end of the string. Always flush stdout before reading to ensure the prompt is visible to the user immediately.