Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. std::io::stdin() / stdout()

std::io::stdin() / stdout()

Since: Rust 1.0(2015)

Rust handles standard I/O through std::io::stdin() and std::io::stdout(). You can read keyboard input line by line with read_line(), and write output using the println!() or write!() macros.

Syntax

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

// Read one line from standard input.
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let trimmed = input.trim(); // Remove the trailing newline.

// Lock stdin for efficiency when reading multiple lines.
let stdin = io::stdin();
for line in stdin.lock().lines() {
    let line = line?;
    println!("{}", line);
}

// Write to standard output.
print!("Enter your input: ");
io::stdout().flush()?; // Flush the buffer immediately.

// Write to standard error.
eprintln!("Error: {}", msg);
writeln!(io::stderr(), "Error details: {}")?;

Method List

Method / FunctionDescription
io::stdin()Returns the standard input handle (a Stdin struct).
stdin.read_line(&mut s)Reads one line (including the newline character) into a String. Returns Result<usize>.
stdin.lock().lines()Locks stdin and returns a line iterator. More efficient when reading multiple lines.
io::stdout()Returns the standard output handle (a Stdout struct).
stdout.flush()Flushes the output buffer immediately. Required after output without a trailing newline.
io::stderr()Returns the standard error handle (a Stderr struct).
input.trim()Removes leading and trailing whitespace and newlines. Always call this after read_line.
s.parse::<T>()Parses a string into another type, such as a number.

Sample Code

sample_main.rs
use std::io::{self, Write};

fn main() {
    print!("Enter your name: ");
    io::stdout().flush().unwrap(); // Display the prompt immediately.

    let mut name = String::new();
    io::stdin().read_line(&mut name).unwrap();
    let name = name.trim(); // Remove the trailing newline.
    println!("Hello, {}!", name);

    print!("Enter your age: ");
    io::stdout().flush().unwrap();

    let mut age_str = String::new();
    io::stdin().read_line(&mut age_str).unwrap();
    let age: u32 = age_str.trim().parse().unwrap_or(0);
    println!("Next year you will be {}", age + 1);

    let num = loop {
        print!("Enter an integer from 1 to 10: ");
        io::stdout().flush().unwrap();

        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();

        match buf.trim().parse::<u32>() {
            Ok(n) if n >= 1 && n <= 10 => break n,
            Ok(_) => eprintln!("Please enter a number between 1 and 10"),
            Err(_) => eprintln!("Please enter a valid integer"),
        }
    };
    println!("You entered: {}", num);
}

Common Mistakes

Mistake 1: Forgetting trim() leaves a trailing newline

read_line() appends the trailing newline character ('\n') to the string. Forgetting to call trim() can cause unexpected behavior in comparisons and type conversions.

stdin_mistake1.rs
use std::io;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    // Without trim(), a trailing \n remains in the string.
    println!("input: '{}'", input); // something like 'hello\n'
    println!("length: {}", input.len()); // one byte longer due to newline

    // Compare with the trimmed version.
    println!("trimmed: '{}'", input.trim());
    println!("trimmed length: {}", input.trim().len());
}

Compile with the following command:

rustc stdin_mistake1.rs
echo "hello" | ./stdin_mistake1
input: 'hello
'
length: 6
trimmed: 'hello'
trimmed length: 5

Mistake 2: Forgetting flush() causes the prompt not to appear

If you do not call flush() after print!() (which does not add a newline), the output may stay in the buffer and the prompt may not appear before the program waits for input.

stdin_flush.rs
use std::io::{self, Write};

fn main() {
    // Without flush(), the prompt may not appear.
    // print!("Enter your name: ");
    // io::stdin().read_line(&mut String::new()).unwrap();

    // Call flush() to write the buffer to the terminal immediately.
    print!("Enter your name: ");
    io::stdout().flush().unwrap();

    let mut name = String::new();
    io::stdin().read_line(&mut name).unwrap();
    println!("Hello, {}!", name.trim());
}

Compile with the following command:

rustc stdin_flush.rs
echo "user_a" | ./stdin_flush
Enter your name: Hello, user_a!

Notes

read_line() appends the trailing newline character ('\n' or '\r\n') to the string. Always call trim() afterward to remove leading and trailing whitespace and newlines before using the value.

To display a prompt immediately after using print!() (which does not add a newline), you need to call io::stdout().flush(). Rust's standard output is buffered, so without a newline the output may remain in the buffer.

For file reading and writing, see File::open() / File::create(). For details on formatted output, see println!() / print!() / format!().

If you find any errors or copyright issues, please .