Skip to content
AgileLogics
6 min read

Reading User Input

Prerequisites: Printing & formatting

User input comes from standard input (stdin), which the standard library exposes through std::io::stdin().

Syntax

use std::io;

let mut line = String::new();
io::stdin()
    .read_line(&mut line)
    .expect("Failed to read line");

Step by step:

  • use std::io; — brings the io module into scope, so you can write io::stdin() instead of std::io::stdin().
  • String::new() — creates an empty, growable String to hold the text. It must be mut because read_line writes into it.
  • .read_line(&mut line) — waits for the user to press Enter, then appends the line to line. &mut line lets the function modify your variable (the References & Borrowing lesson explains &mut).
  • .expect(...) — reading can fail (for example, if stdin is closed); expect stops the program with your message if it does.

The text you get back includes the newline from pressing Enter ("36\n", or "36\r\n" on Windows). Call .trim() to remove surrounding whitespace before using or parsing it.

Example

use std::io;

fn main() {
    println!("What is your name?");
    let mut name = String::new();
    io::stdin()
        .read_line(&mut name)
        .expect("Failed to read line");
    let name = name.trim();

    println!("How old are you?");
    let mut age_text = String::new();
    io::stdin()
        .read_line(&mut age_text)
        .expect("Failed to read line");

    let age: u32 = match age_text.trim().parse() {
        Ok(n) => n,
        Err(_) => {
            println!("That's not a number, using 0.");
            0
        }
    };

    println!("Hello, {name}! Next year you'll be {}.", age + 1);
}

Expected output

If you type Ada and 36, the terminal looks like this (the second and fourth lines are what you typed):

What is your name?
Ada
How old are you?
36
Hello, Ada! Next year you'll be 37.

let name = name.trim(); uses shadowing: the trimmed text replaces the original name from that line on.

Common mistakes

  • Forgetting mut. read_line needs to modify the String:
error[E0596]: cannot borrow `name` as mutable, as it is not declared as mutable
  • Forgetting .trim() before parsing. "36\n".parse::<u32>() fails with invalid digit found in string, because the newline isn't a digit.
  • Reusing one String for several reads. read_line appends, so the second answer is added after the first. Call line.clear() before reading again, or create a new String each time.

Practice

Ask for two whole numbers, one per line, and print their sum. For the inputs 4 and 5, the program should print Sum: 9.

Show solution
use std::io;

fn main() {
    println!("First number:");
    let mut first = String::new();
    io::stdin().read_line(&mut first).expect("Failed to read line");
    let first: i32 = first.trim().parse().expect("Please type a number");

    println!("Second number:");
    let mut second = String::new();
    io::stdin().read_line(&mut second).expect("Failed to read line");
    let second: i32 = second.trim().parse().expect("Please type a number");

    println!("Sum: {}", first + second);
}