如何使用scan_fmt crate的scanln_fmt处理EOF并区分空行?
区分scan_fmt中空行与EOF的处理方案
首先明确scanln_fmt的返回行为:
- 遇到EOF时,函数返回
Err(Error::Eof) - 遇到空行时,因无法匹配指定格式(比如
{d}),会返回Err(Error::NoMatch)或对应格式不匹配的错误
基于这个特性,我们可以通过匹配返回值区分两种情况,实现「空行时x为None,EOF时标记isEOF为true」的逻辑。
基础实现代码
use scan_fmt::{scanln_fmt, Error}; fn main() { loop { let (is_eof, x) = match scanln_fmt!("{d}", i32) { Ok(num) => (false, Some(num)), Err(Error::Eof) => (true, None), Err(_) => (false, None), // 捕获解析失败,含空行、输入非数字等情况 }; println!("isEOF: {}, x: {:?}", is_eof, x); if is_eof { break; } } }
进阶:精准区分空行与其他解析错误
如果需要严格区分空行和其他解析错误(比如输入非数字字符),可以先手动读取整行,再判断内容并解析:
use scan_fmt::{scan_fmt, Error}; use std::io::{self, BufRead}; fn main() { let stdin = io::stdin(); let mut lines = stdin.lock().lines(); loop { let (is_eof, x) = match lines.next() { None => (true, None), // 触发EOF Some(Ok(line)) => { if line.trim().is_empty() { (false, None) // 空行 } else { match scan_fmt!(&line, "{d}", i32) { Ok(num) => (false, Some(num)), Err(_) => (false, None), // 非空行但格式不匹配 } } } Some(Err(_)) => (false, None), // 行读取出错 }; println!("isEOF: {}, x: {:?}", is_eof, x); if is_eof { break; } } }
关键说明
- 直接用
scanln_fmt时,EOF会返回明确的Error::Eof,空行属于格式不匹配错误,可通过错误类型快速区分 - 若要精准识别空行,手动读取整行后判断内容是否为空是更可靠的方式,避免把其他解析错误误判为空行
内容的提问来源于stack exchange,提问作者Megh Parikh
相关产品推荐
相关产品推荐

