Reading Input from the Console in Rust

To read user input from the console in Rust, you use the std::io module, specifically the stdin() function. Input is read as a string, so you must usually trim it and convert it to another type like integer or float using methods like .trim() and .parse().

Reading input from the user is one of the first interactive things you will do in any programming language. Rust provides this capability through its standard library, using std::io.

In this post, I will show you how to read input from the terminal, convert it to different types, and handle possible errors safely.

Basic Input in Rust

To read a line of input, you first need to bring the standard input tools into scope:

use std::io;

Now you can read input like this:

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

    println!("You typed: {}", input);
}

Let us break this down:

  • String::new() creates a new empty string to hold the input
  • io::stdin() gets a handle to the standard input
  • read_line(&mut input) fills the string with what the user types
  • .expect(…) crashes the program if reading fails

This always captures the input as a String, including the newline (\n) at the end.

Trimming and Converting Input

Most of the time, you will want to trim the input and convert it to a number or another type.

Example: reading an integer

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

    let num: i32 = input.trim().parse().expect("Not a number");

    println!("You typed the number: {}", num);
}
  • .trim() removes whitespace like \n
  • .parse() converts the string to the desired type
  • You must specify the target type explicitly (i32 in this case)

Handling Invalid Input Gracefully

Using .expect(…) will crash your program if something goes wrong. For better error handling, you can use a match expression:

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

match input.trim().parse::<i32>() {
    Ok(num) => println!("You typed: {}", num),
    Err(_) => println!("That was not a valid number."),
}

This is safer and more user-friendly, especially when dealing with real users.

Input for Multiple Values

If you want to read several values from one line:

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();

    let parts: Vec<i32> = input
        .trim()
        .split_whitespace()
        .map(|s| s.parse().unwrap())
        .collect();

    println!("You entered: {:?}", parts);
}

This splits the line by spaces and parses each piece as an integer.

Example Program

Here is a small program that asks the user for their name and age, then prints a message:

fn main() {
    let mut name = String::new();
    println!("Enter your name:");
    io::stdin().read_line(&mut name).unwrap();

    let mut age_input = String::new();
    println!("Enter your age:");
    io::stdin().read_line(&mut age_input).unwrap();

    let age: u8 = age_input.trim().parse().unwrap();

    println!("Hello, {}! You are {} years old.", name.trim(), age);
}

Summary

Reading user input in Rust requires using std::io::stdin() and reading into a String. You often need to trim and parse the input to work with numbers. Rust’s type safety and error handling make this process reliable, even if it seems verbose at first.