validation - 如何在Rust和loop中验证用户输入,直到给出有效输入?

标签 validation rust user-input

我正在尝试将营业税Python程序转换为Rust。该程序基本上已经完成,但是我想这样做,以便如果用户没有输入有效的输入(状态美元金额),则该程序会循环执行,直到输入有效的内容为止。

但是,如果输入不存在的状态的缩写,则程序仍然运行并在退出前返回错误的金额。

在Python中,我可以在循环中使用TRY ... EXCEPT进行验证。

我不知道在Rust中是否有类似的方法可以做到这一点。

use std::collections::HashMap;
use std::io;

fn read_one() -> String {
    let mut words = String::new();
    io::stdin()
        .read_line(&mut words)
        .ok()
        .expect("Failed to read line.");
    words
}

fn main() {
    let mut tax_rates = HashMap::new();
    tax_rates.insert("AL".to_string(), 0.04);
    tax_rates.insert("AK".to_string(), 0.00);
    tax_rates.insert("AZ".to_string(), 0.056);
    tax_rates.insert("AR".to_string(), 0.65);
    tax_rates.insert("CA".to_string(), 0.725);
    tax_rates.insert("CO".to_string(), 0.029);
    tax_rates.insert("CT".to_string(), 0.635);
    tax_rates.insert("DE".to_string(), 0.00);
    tax_rates.insert("DC".to_string(), 0.06);
    tax_rates.insert("FL".to_string(), 0.06);
    tax_rates.insert("GA".to_string(), 0.04);
    tax_rates.insert("HI".to_string(), 0.04);
    tax_rates.insert("ID".to_string(), 0.06);
    tax_rates.insert("IL".to_string(), 0.0625);
    tax_rates.insert("IN".to_string(), 0.07);
    tax_rates.insert("IA".to_string(), 0.06);
    tax_rates.insert("KS".to_string(), 0.065);
    tax_rates.insert("KY".to_string(), 0.06);
    tax_rates.insert("LA".to_string(), 0.0445);
    tax_rates.insert("ME".to_string(), 0.055);
    tax_rates.insert("MD".to_string(), 0.06);
    tax_rates.insert("MA".to_string(), 0.0625);
    tax_rates.insert("MI".to_string(), 0.06);
    tax_rates.insert("MN".to_string(), 0.06875);
    tax_rates.insert("MS".to_string(), 0.07);
    tax_rates.insert("MO".to_string(), 0.0425);
    tax_rates.insert("MT".to_string(), 0.00);
    tax_rates.insert("NE".to_string(), 0.055);
    tax_rates.insert("NV".to_string(), 0.0685);
    tax_rates.insert("NH".to_string(), 0.00);
    tax_rates.insert("NJ".to_string(), 0.06625);
    tax_rates.insert("NM".to_string(), 0.05125);
    tax_rates.insert("NY".to_string(), 0.04);
    tax_rates.insert("NC".to_string(), 0.0475);
    tax_rates.insert("ND".to_string(), 0.05);
    tax_rates.insert("OH".to_string(), 0.0575);
    tax_rates.insert("OK".to_string(), 0.045);
    tax_rates.insert("OR".to_string(), 0.00);
    tax_rates.insert("PA".to_string(), 0.06);
    tax_rates.insert("RI".to_string(), 0.07);
    tax_rates.insert("PR".to_string(), 0.115);
    tax_rates.insert("SC".to_string(), 0.06);
    tax_rates.insert("SD".to_string(), 0.045);
    tax_rates.insert("TN".to_string(), 0.07);
    tax_rates.insert("TX".to_string(), 0.0625);
    tax_rates.insert("UT".to_string(), 0.0485);
    tax_rates.insert("VA".to_string(), 0.043);
    tax_rates.insert("VT".to_string(), 0.06);
    tax_rates.insert("WA".to_string(), 0.065);
    tax_rates.insert("WV".to_string(), 0.06);
    tax_rates.insert("WI".to_string(), 0.05);
    tax_rates.insert("WY".to_string(), 0.04);

    println!("In what state are you making your purchase?");
    let state = read_one();
    let state = state.trim().to_uppercase();

    println!("How many items are you purchasing?");
    let purchase_number = read_one();
    let purchase_number = purchase_number.trim().parse::<i32>().unwrap();

    match tax_rates.get(&state) {
        Some(rate) => {
            println!("The tax rate for {} is ({}).", state, rate);
        }
        None => {
            println!("None.");
        }
    }

    let mut tax_vec = Vec::new();
    let mut cost_vec = Vec::new();

    for item_number in 0..purchase_number {
        println!("What is the cost of item number {}?", item_number + 1);
        let item_cost = read_one();
        let item_cost = item_cost.trim().parse::<f64>().unwrap();

        match tax_rates.get(&state) {
            Some(rate) => {
                let tax_amount = item_cost * rate;
                let fin_cost = item_cost + tax_amount;
                println!(
                    "The tax amount for item {} is: {:.2}",
                    item_number, tax_amount
                );
                println!(
                    "The final cost of item number {} is: {:.2}",
                    item_number, fin_cost
                );

                tax_vec.push(tax_amount);
                cost_vec.push(fin_cost);
            }

            None => {
                println!("None.");
            }
        }
    }

    let mut t_total = 0.00;
    let mut c_total = 0.00;

    for i in tax_vec {
        t_total += i
    }

    for b in cost_vec {
        c_total += b
    }
    println!("Your total tax amount is {:.2}", t_total);
    println!("Yout total cost is {:.2}", c_total);
}

如何验证Rust中的用户输入?

最佳答案

我建议重复循环,直到您的程序知道它具有有效的输入为止。

尝试替换此代码:

println!("In what state are you making your purchase?");
let state = read_one();
let state = state.trim().to_uppercase();

使用此代码:
let mut state: String;
loop {
    println!("In which state are you making your purchase?");
    state = read_one().trim().to_uppercase();

    if tax_rates.contains_key(&state) {
        break
    }

    println!("Invalid state.  Please try again.")
}

这仅处理state输入,因此您必须与其他输入变量做类似的事情。

关于validation - 如何在Rust和loop中验证用户输入,直到给出有效输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59584975/

相关文章:

javascript - 我正在尝试在 javascript 中验证没有警报功能的文本字段,但它不起作用

php - 在 Yii 的文本字段中显示错误消息

php - 验证美国电话号码

Applescript 显示对话框用户输入

c# - 如何获取绘图板笔压力值?

c - getchar/putchar、gets/puts 和 fgets/fputs(C 语言)之间有什么区别?

javascript - 表单验证 - html 和 javascript

rust - 用零字节填充向量的最佳方法?

logging - 是否可以覆盖类型的现有 Debug 实现?

generics - 通用函数接受 &str 或移动字符串而不复制