Rust字符串不区分大小写比较方法及游戏代码失效问题求助
Rust石头剪刀布程序"Invalid Response"问题修复
核心问题
你遇到的所有输入都触发"Invalid Response"的原因是:io::stdin().read_line(&mut guess)会把输入末尾的换行符(\n)也读取到字符串中。比如你输入rock,实际guess存储的是"rock\n",和你用来比较的"rock"、"paper"等字符串不相等,导致所有条件判断都不成立,最终走到默认的错误输出分支。
解决方案
读取输入后,必须先去除字符串首尾的空白字符(包括换行符、多余空格),可以使用trim()方法,之后再进行比较或转换大小写。
修复后的当前版本代码
use std::io; use std::thread; use std::time; use rand::Rng; fn start_next() { thread::sleep(time::Duration::from_secs(3)); rps(); } fn rps() { let rk = String::from("rock"); let pp = String::from("paper"); let sc = String::from("scissors"); let end = String::from("end"); let mut guess = String::new(); println!("Choose one (\"end\" to quit):\n- rock\n- paper\n- scissors"); io::stdin().read_line(&mut guess).expect("Unable to read line"); // 关键修复:去除首尾空白字符(包括换行符) guess = guess.trim().to_string(); let aichoice = ["rock", "paper", "scissors"][rand::thread_rng().gen_range(0..3)]; // debug println!("\nAI chose {}", aichoice); println!("You chose {}", guess); if guess.eq_ignore_ascii_case(&rk) { match aichoice { "rock" => println!("Your moves canceled out."), "paper" => println!("Paper defeated your rock."), "scissors" => println!("You defeated scissors"), _ => {} } start_next(); return; } if guess.eq_ignore_ascii_case(&pp) { match aichoice { "rock" => println!("You defeated rock."), "paper" => println!("Your moves canceled out."), "scissors" => println!("Scissors defeated your paper."), _ => {} } start_next(); return; } if guess.eq_ignore_ascii_case(&sc) { match aichoice { "rock" => println!("Rock defeated your scissors."), "paper" => println!("You defeated paper."), "scissors" => println!("Your moves canceled out."), _ => {} } start_next(); return; } if guess.eq_ignore_ascii_case(&end) { return; } println!("Invalid response"); start_next(); }
注:同时修复了随机数生成的写法,rand::random::<u8>() %3替换为更规范的rand::thread_rng().gen_range(0..3),需确保Cargo.toml中添加了rand依赖。
修复后的to_lowercase+match版本代码
你之前的match版本除了未处理换行符外,还存在语法错误(Rust的match不需要case关键字),修复后如下:
use std::io; use std::thread; use std::time; use rand::Rng; fn rps() { let mut guess = String::new(); println!("Choose one (\"end\" to quit):\n- rock\n- paper\n- scissors"); io::stdin().read_line(&mut guess).expect("Unable to read line"); // 先去除换行符,再转小写 let guess2 = guess.trim().to_lowercase(); let aichoice = ["rock", "paper", "scissors"][rand::thread_rng().gen_range(0..3)]; match guess2.as_str() { "rock" => { match aichoice { "rock" => println!("Your moves canceled out."), "paper" => println!("Paper defeated your rock."), "scissors" => println!("You defeated scissors"), _ => {} } } "paper" => { match aichoice { "rock" => println!("You defeated rock."), "paper" => println!("Your moves canceled out."), "scissors" => println!("Scissors defeated your paper."), _ => {} } } "scissors" => { match aichoice { "rock" => println!("Rock defeated your scissors."), "paper" => println!("You defeated paper."), "scissors" => println!("Your moves canceled out."), _ => {} } } "end" => return, _ => println!("Invalid Response"), } thread::sleep(time::Duration::from_secs(3)); rps(); }
额外说明
trim()会去除字符串首尾的所有空白字符(包括空格、制表符、换行符),如果只想去除末尾的换行符,也可以使用trim_end()或trim_matches('\n')。- 不区分大小写的字符串比较,除了
eq_ignore_ascii_case(仅支持ASCII字符),如果需要支持非ASCII字符的大小写不敏感比较,可以使用unicasecrate。
内容的提问来源于stack exchange,提问作者a human being
相关产品推荐
相关产品推荐

