rust Read_line()在循环中不等待用户输入,

pnwntuvh  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(147)

程序应该做什么?

1.从端子读取两个以空格分隔的数字,例如“10 8”。
1.将字符串拆分为Vec<&str>
1.将Vec[0]Vec[1]解析为num1num2
1.从终端读取(数学)操作并解析。
1.打印“数学”和结果。(10 * 80 = 80)
1.捕获步骤2. - 4.中的几乎所有错误,并运行try_again函数。
1.如果一切正常,则运行try_again函数,并显示“Success”msg
(the main函数仅用于上下文,问题出在try_again函数中)

use std::io::{self, Write, Read, Error, ErrorKind};

const ERR_MSG_STDIN_READ: &str = "Problem with getting input";
const ERR_MSG_STDOUT_FLUSH: &str = "Problem with flushing stdout";

fn main() {
    loop {
        clear_terminal();

        print!("Write 2 ints separated by space: ");
        let mut nums_string = String::new();
        io::stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
        io::stdin().read_line(&mut nums_string).expect(ERR_MSG_STDIN_READ);
        let nums_str_vec: Vec<&str> = nums_string.trim()
.split(' ').collect();
        let num1: i32 = match nums_str_vec[0].parse() {
            Ok(num) => num,
            Err(_) => match try_again("Error") {
                true => continue,
                false => break
            }
        };
        let num2: i32 = match nums_str_vec[1].parse() {
            Ok(num) => num,
            Err(_) => match try_again("Error") {
                true => continue,
                false => break
            }
        };

        print!("Write one of these[+,-,*,/] maths operation for 2 inputed ints: ");
        let mut operation_string = String::new();
        io::stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
        io::stdin().read_line(&mut operation_string).expect(ERR_MSG_STDIN_READ);
        let operation = match operation_string.trim().parse() {
            Ok(char) => char,
            Err(_) => match try_again("Error") {
                true => continue,
                false => break
            }
        };
        match operation {
            '+' => println!("{} {} {} = {}", num1, operation, num2, num1 + num2),
            '-' => println!("{} {} {} = {}", num1, operation, num2, num1 - num2),
            '*' => println!("{} {} {} = {}", num1, operation, num2, num1 * num2),
            '/' => println!("{} {} {} = {} ({})", num1, operation, num2, num1 / num2, num1 % num2),
            _ => match try_again("Error") {
                true => continue,
                false => break
            }
        }
        io::stdin().read(&mut [0]).expect(ERR_MSG_STDIN_READ);
        match try_again("Success") {
            true => continue,
            false => break
        }
    }
}

fn clear_terminal() {
    print!("{}c", 27 as char);
    io::stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
}

try_again函数应执行哪些操作?

1.将msg保存为msg_new,以便以后更改。
1.从终端读取(y/n)答案并解析。
1.如果“是”,则返回true;如果“否”,则返回false
1.捕获步骤2中的几乎所有错误,并再次继续“自循环”。(带有“错误”msg
1.程序(在main函数中)匹配try_again函数的返回结果=〉true表示继续主循环,false表示中断循环并结束程序。

fn try_again(msg: &str) -> bool {
    let mut msg_new = msg;
    loop {
        println!("The calculation end up with {}.", msg_new);
        print!("Do you want to make antoher calculation? (y/n): ");
        let mut answer_string = String::new();
        stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
        stdin().read_line(&mut answer_string).expect(ERR_MSG_STDIN_READ);
        match answer_string.trim().chars().next() {
            Some('y') => true,
            Some('n') => false,
            _ => {
                msg_new = "Error";
                continue
            }
        };  
    }
}

∮ ∮有什么问题?∮

程序中哪些部分不起作用?

步骤7 (也许我们可以说6和7) 问题出在try_again函数中。

try_again函数中不起作用的内容

当程序运行try_again("Success");时:
1.在第一个循环中,stdin().read_line(&mut next_string)不等待用户输入,而是立即转到_ => arm。
1.并再次继续“自循环”(出现“错误”msg
1.在第二个循环中,实际上等待输入并工作,但使用错误的msg

最后一个问题

为什么stdin().read_line(&mut next_string)在第二轮循环中等待输入?如何解决?感谢各位的回答!

我是完全新生 rust ,请解释 * 一切 * 你写的。OS:Windows 10,终端:cmd(命令提示)

umuewwlo

umuewwlo1#

您必须检查是否输入了'y''n',例如,是否带有保护符:

fn next(msg: &str) -> bool {
    let msg_new = msg;
    loop {
        clear_terminal();
    
        println!("The calculation end up with {}.", msg_new);
        print!("Do you want to make antoher calculation? (y/n): ");
        let mut next_string = String::new();
        stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
        match std::io::stdin().read_line(&mut next_string) {
            Ok(n) if n > 0 && next_string.chars().next().unwrap() == 'y' => break true,
            Ok(n) if n > 0 && next_string.chars().next().unwrap() == 'n' => break false,
            Ok(_) => {},  // other input is ignored
            Err(err) => panic_any(err),
        };
    }
}

顺便说一句:next应该保留给迭代器使用

相关问题