在Rust中有丢弃输入的标准方法吗?

时间:2016-09-06 14:24:12

标签: io rust stdin

从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之前,它可以读取任意数量的字符,忽略它并且不返回任何内容或io::Result。有没有标准的方法,或者我必须自己实施?我跟踪了read_line实施的BufReadread_until的实施情况,但我不确定从那里开始是不是一个好主意。

2 个答案:

答案 0 :(得分:1)

您可以在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");
}

答案 1 :(得分:0)

我尝试使用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(())
    }
}

我欢迎尝试设计更简单的解决方案。