首页 > 解决方案 > 在 C++ 的`std::cin >>` 的 Rust 模拟中,我缺少什么极端情况?

问题描述

我的计划是编写一个简单的方法,该方法完全符合std::cin >>C++ 标准库的功能:

use std::io::BufRead;

pub fn input<T: std::str::FromStr>(handle: &std::io::Stdin) -> Result<T, T::Err> {
    let mut x = String::new();
    let mut guard = handle.lock();
    loop {
        let mut trimmed = false;
        let available = guard.fill_buf().unwrap();
        let l = match available.iter().position(|&b| !(b as char).is_whitespace()) {
            Some(i) => {
                trimmed = true;
                i
            }
            None => available.len(),
        };
        guard.consume(l);
        if trimmed {
            break;
        }
    }
    let available = guard.fill_buf().unwrap();
    let l = match available.iter().position(|&b| (b as char).is_whitespace()) {
        Some(i) => i,
        None => available.len(),
    };
    x.push_str(std::str::from_utf8(&available[..l]).unwrap());
    guard.consume(l);
    T::from_str(&x)
}

loop意味着在有效输入开始之前修剪掉所有空白。循环外的match块是计算有效输入长度的地方(即,在尾随空格开始或EOF到达之前)。

这是使用上述方法的示例。

let handle = std::io::stdin();
let x: i32 = input(&handle).unwrap();
println!("x: {}", x);
let y: String = input(&handle).unwrap();
println!("y: {}", y);

当我尝试了一些简单的测试时,该方法按预期工作。但是,当我在 codeforces 等在线编程判断中使用它时,我收到一条抱怨,告诉我程序有时会保持空闲状态或输入错误,以及其他问题,这导致怀疑我错过了一个极端情况或类似的东西。这通常发生在输入有几百行长的时候。

什么输入会破坏方法?修正是什么?

标签: rust

解决方案


经过大量实验后,我注意到读取每个输入时都会出现延迟,随着输入数量的增加而增加。该函数不使用缓冲区。每次需要填充变量时,它都会尝试访问流,这很慢,因此会出现滞后。

经验教训:始终使用容量大的缓冲区。

但是,闲置问题仍然存在,直到我将fill_buf,consume对替换为类似的东西read_lineor read_string


推荐阅读