Rust match表达式内多轮用户输入首轮读取跳过问题排查
问题根源
输入跳过现象和match表达式没有任何关系,是标准输入缓冲区残留换行符未被处理导致的:
text_io库的read!()宏读取字符串时,默认读到空白字符(空格、换行、制表符等)就会停止读取- 你输入游戏模式选项
1后按下的回车键会生成\n换行符,read!()仅读取了"1"赋值给game_mode,\n会残留在输入缓冲区中 - 第一次调用
player_input()时,read_line()会直接读取到缓冲区里残留的\n,直接返回带换行的空字符串,就呈现出跳过第一个玩家输入的现象。
修复方案
两种可选修复方式,可按需选择:
方式1:移除text_io依赖,统一用标准库std::io读取所有输入
该方式输入逻辑统一,无需额外处理缓冲区残留,更稳妥:
use std::io; fn player_input() -> String { let mut input = String::new(); io::stdin() .read_line(&mut input) .expect("Wrong input"); // 移除输入末尾的换行符,避免后续打印出现多余空行 input.trim_end().to_string() } fn main() { println!("GAME MODE"); println!("1. Human Vs Human"); println!("2. Human Vs Machine"); // 用标准库read_line读取游戏模式选择 let mut game_mode = String::new(); io::stdin() .read_line(&mut game_mode) .expect("Wrong input"); let game_mode = game_mode.trim(); match game_mode { "1" => { println!("Player 1 : \n"); let player_1 = player_input(); println!("Player 2 : "); let player_2 = player_input(); println!("{} - {}", player_1, player_2); }, "2" => { println!("Player 1 : "); let player_1 = player_input(); let player_2 = "Skynet"; println!("{} - {}", player_1, player_2); }, _ => println!("Wrong input"), }; }
方式2:保留text_io依赖,手动清理残留换行
在读取游戏模式的代码后新增一行清理缓冲区的代码即可:
let game_mode : String = read!(); // 新增:吃掉输入缓冲区残留的换行符 io::stdin().read_line(&mut String::new()).unwrap();
建议同时在player_input返回时调用trim_end()移除输入末尾的换行符,避免打印异常。
内容的提问来源于stack exchange,提问作者Spkf
相关产品推荐
相关产品推荐

