The issue is that read_line
appends a newline character to the end of the string. If you want to remove it, you can use trim
, which removes whitespace from both ends, or trim_end
, which removes trailing whitespace only:
use std::io;
fn input() -> String {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("cannot read line");
input.trim().to_string()
}
Alternatively, you can use BufRead::lines
:
use std::io::{self, prelude::*};
fn input() -> String {
io::stdin()
.lock()
.lines()
.next()
.and_then(|res| res.ok())
.expect("cannot read line")
}
This approach is better IMO for reading a line, since it
-
avoids reinventing the wheel;
-
removes only the trailing newline character, not all trailing whitespace, and is thus more semantically accurate (note that you can still add a .trim()
to the chain if you additionally want to discard whitespace);
-
avoids the explicit creation of a mut
variable;
-
avoids an extra allocation (you can of course check for a newline character and use pop
in the first approach, but that would be more verbose; see the first bullet);
-
allows you to differentiate between EOF and other kinds of I/O error, as shown below:
// returns None for EOF
fn input() -> Option<String> {
io::stdin()
.lock()
.lines()
.next()
.map(|res| res.expect("cannot read line"))
}