if语句C ++期间意外中断

Posted

技术标签:

【中文标题】if语句C ++期间意外中断【英文标题】:Unexpected break during an if statement C++ 【发布时间】:2020-06-24 09:55:46 【问题描述】:

该程序是将日元、欧元或英镑(取决于用户输入)转换为美元。 我要求 2 个用户输入 - 双倍金额(要兑换的钱)和 char 货币(以确定要兑换成美元的货币)。 样本输入:1y 样本输出:1 日元 = 0.0094 美元。 当我尝试将欧元转换为美元时,问题出在 if-else 块中,它打破了 while 循环。这是我的代码:

double amount; // the amount of money to be converted
char currency; // to determine the currency in which the money is being entered in.
    while (cin >> amount >> currency) 
        if (currency == 'y' || currency == 'Y') 
            cout << amount << " yen(s) = " << (amount * 0.0094) << " dollar(s).\n";
        
        else if (currency == 'e' || currency == 'E') 
            cout << amount << " euro(s) = " << (amount * 1.13) << " dollar(s).\n";
        
        else if (currency == 'p' || currency == 'P') 
            cout << amount << " pound(s) = " << (amount * 1.25) << " dollar(s).\n";
        
        else 
            cout << "Sorry I did not recognize the currency! Please enter 'y','e' or 'p'.\n";
        
        cout << "Please enter the amount of money and corresponding currency to covert to  dollars: ";
    

这里有我输入和输出的图像作为证据:

欧元兑换美元错误一

欧元兑换美元错误二

【问题讨论】:

请在问题中包含minimal reproducible example。 amountcurrency 是什么? 可能当您输入1e2E 时,程序会将其视为单个值(科学记数法)并退出您的while 循环。 1Y 和 1P 可以解释为 1 个十进制数和 1 个字符,但 1E 可以解释为单个十六进制数,没有字符,打破循环的条件。 @Shayna "所以当它读取 "1E" 时,它会将其存储为数量,因为 1E 转换为十进制 30,它适合双精度数。" 不不。在您提出索赔之前,您是否尝试过验证您的索赔? std::cin,可以读取科学计数法中的数字(例如 1E+1),所以当它看到 1E 时,它期望这种形式的数字,但由于没有指数 - std::cin 失败。这就是循环停止的原因:由于输入操作失败。 我不是要求进一步最小化代码,而是要添加缺少的细节。您只在文本中提及类型是什么,但在代码中缺少声明。如果您的代码可以被其他人复制以重现您面临的相同问题,那总是更容易 【参考方案1】:

提供一个实际的答案,因为我不能在 cmets 中这样做;这是获取相关用户输入的另一种方法,保持相同的语法。这假定输入字符串的最后一个字符是货币字符。您可以检查最后一个字符是否为有效的货币字符,但这里有一个简化版本。

#include <iostream>
#include <string>

int main() 
    std::string input_string;
    std::getline(std::cin, input_string);

    if(input_string.size() >= 2) 
        char currency = input_string[input_string.size() - 1];
        input_string[input_string.size() - 1] = '\0';
        double amount = std::stof(input_string);

        std::cout << amount << std::endl;
        std::cout << currency << std::endl;
    

【讨论】:

为什么你的情况 >= 2?它不应该是“== 2”吗?因为我只接受 2 个字符,而不是更多或更少。 @ProgrammingRage 因为你可以有一个像 56.573 这样的数量,它仍然是一个有效的双精度数。但是,如果您想将其限制为数字 0-9,则可以将其替换为 ==。 @ProgrammingRage 如果您的输入始终是一个数字和一个字符,则将 amount 设为整数,整个问题就解决了。整数没有科学记数法。 哦,是的!真的。太感谢了!另外,由于我是初学者,感谢您对我不苛刻! @ProgrammingRage 没问题 :) *** 有时可能非常残酷,我亲身体验过。我最不想成为的就是它的原因。【参考方案2】:

amount 是一个浮点变量。而1e 是浮点数的开头; e 是指数前缀,如1e5=10000.0

所以cin1e 视为一个格式错误的浮点数,并中止操作,返回false(并在amount 变量中返回0.0,同时保持currency 不变) .如果您将amount 声明为int,它会按预期工作。

或者您可以使用 Shayna 的解决方案。

【讨论】:

如果用户只输入“1e”以避免意外中断和此类差异,是否没有默认格式?我相信这很重要,因为它会产生一些结果而不是没有,在调试时我可以自己弄清楚为什么这个输出而不是什么都没有? @ProgrammingRage:我不明白你的问题。 (顺便说一句,我自己从不使用cin,除非在一次性代码中。它太死板了。) 因此 cin 将 1e 视为一个数字,并期望将 '1e+1' 等格式作为科学记数法。因此,如果用户只键入“1e”,那么他们必须使用的算法将会中断,因为它不受格式的限制。现在,如果有一个默认数字,以防用户没有输入整个格式,它不会中断并会给出一些输出。该输出将不正确,但至少它会告诉我输出不正确的原因。例如,如果我只输入 2e,它应该会自动更改为 2e+1 或其他一些默认格式。对吗? @ProgrammingRage:不,这不是编程语言的工作方式。像这样报告虚构的数字是错误的。 @ProgrammingRage -- double amount; std::cin &gt;&gt; amount; 在该代码中,选择了读取double 值的&gt;&gt; 运算符。 “1e”不是有效的双精度值。之后,if (std::cin) 将看到 std::cinfalse。这就是你恢复的方式:检查输入是否成功。

以上是关于if语句C ++期间意外中断的主要内容,如果未能解决你的问题,请参考以下文章

VBScript没有超过if语句

为啥在SQL语句的GROUP BY里面不可以使用别名

Python_02

是否有任何工具可以帮助处理复杂的“如果”逻辑?

MyBatis_动态SQL

箭头主体周围出现意外的块语句