Reading input from stdin
in Rust is pretty straightforward:
use std::io;
let mut some_string = String::new();
let _ = io::stdin().read_line(&mut some_string);
but sometimes you might want to just discard it without acknowledging it anywhere or procuring a buffer, like:
println!("Press Enter to close");
io::stdin().discard_input(); // discard_input() doesn't exist
It could read any number of characters until encountering \n
, ignore it all and return nothing or io::Result
. Is there a standard way of doing it or do I have to implement it myself? I traced the implementation of read_line
to read_until
implemented by BufRead
, but I'm not sure if it's a good idea to start from there.
You can implement .discard_until_newline()
on stdin for example like this:
This should be a correct and efficient implementation (using a buffer to read, but not copying the read parts anywhere). It could be much simpler if you don't anticipate any long lines and just read a byte at a time, of course.
use std::io::Stdin;
use std::io;
use std::io::prelude::*;
pub trait DiscardUntil {
fn discard_until_newline(&mut self) -> Result<(), io::Error>;
}
impl DiscardUntil for Stdin {
fn discard_until_newline(&mut self) -> Result<(), io::Error> {
let mut buffered = self.lock();
loop {
let (consume, done) = {
let data = try!(buffered.fill_buf());
if data.is_empty() {
(0, true)
} else if let Some(newline_pos) = data.iter().position(|b| *b == b'\n') {
(newline_pos + 1, true)
} else {
(data.len(), false)
}
};
buffered.consume(consume);
if done {
break;
}
}
Ok(())
}
}
fn main() {
println!("hi");
io::stdin().discard_until_newline().unwrap();
println!("again");
io::stdin().discard_until_newline().unwrap();
println!("goodbye");
}