【问题标题】:Strange BUG in C++ iostream?C++ iostream 中的奇怪 BUG?
【发布时间】:2017-11-02 09:52:43
【问题描述】:

这是 iostream 中的错误吗? ...

        #include<iostream>
        void money_conversion (){

        constexpr double dollars_in_yen=0.01;
        constexpr double dollars_in_euro=1.16;
        constexpr double dollars_in_pound=1.33;
        std::cout<<"Supported valutes : yen ('y'), euros('e'), pounds('p').\n";
        std::cout<<"Please enter the value + valute that you want to convert into dollars! :";
        double value=1;
        char valute=0;
        while(true){
        std::cin>>value>>valute;
        if(valute=='y')
            std::cout<<"\n\n"<<value<<" yens is "<<value*dollars_in_yen<<" dollars. \n";
        else if(valute=='e')
            std::cout<<"\n\n"<<value<<" euros is "<<value*dollars_in_euro<<" dollars. \n";
        else if(valute=='p')
            std::cout<<"\n\n"<<value<<" pounds is "<<value*dollars_in_pound<<" dollars. \n";
        else
            std::cout<<"\n\nSorry, unknown valute ("<<valute<<").\n";
        }

    }


    int main(){

        money_conversion();
        return 0;

    }

当键盘输入时

  • '5p' 或

  • '5 p'或

  • '3y' 或

  • “3 岁”或

  • '1 z' 或

  • 1z' 或

  • '10 e'

一切都按预期进行。

当输入为'(anyting)e' 时,它是一个错误(如'5e') 我已经尝试了几乎所有方法以使其正常工作,但没有成功。

当我删除 while() 循环时,我在输入 '5e' 时得到此输出 -> "Sorry, unknown valute ( )" 但是当我输入时可以说'7m' 我得到输出"Sorry, unknown valute (m)."

我认为这很重要,因为在大型代码中,这可能是一个几乎不可能注意到的错误。 'e' 在某些情况下作为char 输入是否存在问题?

【问题讨论】:

  • 我猜e 被解析为浮点指数的一部分。
  • 是的,'5e2' 与 '500' 一样,所以它缺少输入的其余部分,这就是它变成无限循环的原因。谢谢,上帝保佑
  • @tobi303 将 7m 读取为 double 是明确定义的:它应该读取 7 并将 m 留在流中
  • @M.M 哦,真的吗?然后我学到了一些东西;)
  • 经验法则:当问题是“数百万人使用的这个库中是否存在错误”时,答案很可能是“否”。在使用 C++ 20 年后,我仍然使用这个假设。

标签: c++ iostream


【解决方案1】:

std::istreamstd::locale 库函数尝试解析任何数字输入时,它总是首先抓取集合"0123456789abcdefxABCDEFX+-" 中的所有连续字符,这些字符可能对正在执行的转换类型有效,然后才试图确定它们的含义。见Stage 2 of the num_get processing的描述。

因此,在您的 "5e" 示例中,operator&gt;&gt;(double&amp;) 函数同时获取 '5''e',期望在 'e' 之后找到一个指数,但停在那里,并且这些字符无效完成double

【讨论】:

  • 我有点明白你在说什么,但是。 '5c' 输入给出合法输出:'对不起,未知值(c)。并且没有无限循环错误。与 a, b, d, f 相同。只有 '(number)e' 是问题 - '5e2e' 产生合法输出:“500 欧元是 580 美元。”
  • 希望有一天,如果 0o 成为八进制文字的前缀,我们可以将 o 添加到该列表中。
  • 您遗漏了第 2 阶段的关键部分:“进行检查以确定是否允许 c 作为第 1 阶段返回的转换说明符的输入字段的下一个字符。”这条规则就是为什么7a7b 等都可以但7e 不行
  • @M.M 谢谢,我完全错过了那部分!现在应该更正确了。
【解决方案2】:

不,这不是 C++ 流类中的错误。

您需要以std::string 的形式读入输入,然后自己提取价值和货币。

那是因为e用于分隔科学记数法中的有效数指数,这是另一种指定@的方式987654323@。因此10e 是无效的double,因为它缺少定义指数的部分。

顺便说一句,使用 GBP、EUR 和 JPY(它们是您想要支持的货币的 ISO 代码)会不那么特别。

【讨论】:

  • 我建议提取一个整数,然后如果下一个字符是.,则提取另一个整数
  • 公平点 - 从当前语言环境中提取正确的字符 :)
猜你喜欢
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-30
  • 1970-01-01
相关资源
最近更新 更多