在 Rust 中是否有丢弃输入的标准方法?
Is there a standard way of discarding input in Rust?
在 Rust 中从 stdin
读取输入非常简单:
use std::io;
let mut some_string = String::new();
let _ = io::stdin().read_line(&mut some_string);
但有时您可能只想丢弃它而不在任何地方确认它或获取缓冲区,例如:
println!("Press Enter to close");
io::stdin().discard_input(); // discard_input() doesn't exist
它可以读取任意数量的字符,直到遇到 \n
,将其全部忽略并且 return 什么都不读或 io::Result
。有没有标准的方法,还是我必须自己实施?我将 read_line
的实现追踪到 BufRead
实现的 read_until
,但我不确定从那里开始是否是个好主意。
您可以在 stdin 上实现 .discard_until_newline()
,例如:
这应该是一个正确且高效的实现(使用缓冲区读取,而不是将读取的部分复制到任何地方)。当然,如果您不预期任何长行并且一次只读取一个字节,它可能会简单得多。
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");
}
我试验了 bluss 的代码,并能够提出一个性能稍差并且不太适合某些极端情况(见下面的评论)但更简单和更短的实现:
use std::io;
use std::io::{Stdin, BufRead};
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();
let amount = {
let data = try!(buffered.fill_buf());
data.len()
};
buffered.consume(amount);
Ok(())
}
}
我欢迎尝试设计一个更简单的解决方案。
在 Rust 中从 stdin
读取输入非常简单:
use std::io;
let mut some_string = String::new();
let _ = io::stdin().read_line(&mut some_string);
但有时您可能只想丢弃它而不在任何地方确认它或获取缓冲区,例如:
println!("Press Enter to close");
io::stdin().discard_input(); // discard_input() doesn't exist
它可以读取任意数量的字符,直到遇到 \n
,将其全部忽略并且 return 什么都不读或 io::Result
。有没有标准的方法,还是我必须自己实施?我将 read_line
的实现追踪到 BufRead
实现的 read_until
,但我不确定从那里开始是否是个好主意。
您可以在 stdin 上实现 .discard_until_newline()
,例如:
这应该是一个正确且高效的实现(使用缓冲区读取,而不是将读取的部分复制到任何地方)。当然,如果您不预期任何长行并且一次只读取一个字节,它可能会简单得多。
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");
}
我试验了 bluss 的代码,并能够提出一个性能稍差并且不太适合某些极端情况(见下面的评论)但更简单和更短的实现:
use std::io;
use std::io::{Stdin, BufRead};
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();
let amount = {
let data = try!(buffered.fill_buf());
data.len()
};
buffered.consume(amount);
Ok(())
}
}
我欢迎尝试设计一个更简单的解决方案。