Why doesn't my user input from stdin match correctly?


Keywords:rust 


Question: 

I'm trying to get system input and check if the user put in yes or no. Am I doing my string conversion wrong or something? The if block doesn't execute.

use std::io;

fn main() {
    let mut correct_name = String::new();
    io::stdin().read_line(&mut correct_name).expect("Failed to read line");
    if correct_name == "y" {
        println!("matched y!");
        // Do something
    } else if correct_name == "n" {
        println!("matched n!");
        // Do something else
    }
}

3 Answers: 

read_line includes the terminating newline in the returned string. Add .trim_right_matches("\r\n") to your definition of correct_name to remove the terminating newline.



Instead of trim_right_matches, I'd recommend using trim_right or even better, just trim:

use std::io;

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

    let correct_name = correct_name.trim();

    if correct_name == "y" {
        println!("matched y!");
        // Do something
    } else if correct_name.trim() == "n" {
        println!("matched n!");
        // Do something else
    }
}

This last case handles lots of types of whitespace:

Returns a string slice with leading and trailing whitespace removed.

'Whitespace' is defined according to the terms of the Unicode Derived Core Property White_Space.

So Windows / Linux / macOS shouldn't matter.


You could also use the trimmed result's length to truncate the original String, but in this case you should only use trim_right!

let trimmed_len = correct_name.trim_right().len();
correct_name.truncate(trimmed_len);


You can use the chomp-nl crate which provides a chomp function which returns a string slice without the newline characters.

There is also a trait ChompInPlace if you prefer to do this in-place.

Disclaimer: I am the author of this library.