以字符'e'作为输入并进行比较

5

好的,我正在做一本书中的练习,将不同类型的货币转换为美元。但是当我在 if 语句中将 'e' 作为 char 变量的输入并进行比较时,比较不起作用,但如果我用其他字母替换它,则可以正常工作。怎么回事?以下是代码:

int main()
{
    const double yen_per_dollar = .013;
    const double pound_per_dollar = 1.55;
    const double euro_per_dollar = 1.29;

    double amount = 1;
    char unit = ' ';

    std::cout << "Please enter a amount followed by a unit (p, y, or e): ";
    std::cin >> amount >> unit;

    if (unit == 'y')
        std::cout << amount << " yen is $" << amount * yen_per_dollar << " dollars.\n";
    if (unit == 'p')
        if (amount == 1)
            std::cout << amount << " pound is $" << amount * pound_per_dollar << " dollars.\n";
        else
            std::cout << amount << " pounds is $" << amount * pound_per_dollar << " dollars.\n";
    if (unit == 'e')
        if (amount == 1)
            std::cout << amount << " euro is $" << amount * euro_per_dollar << " dollars.\n";
        else
            std::cout << amount << " euros is $" << amount * euro_per_dollar << " dollars.\n";
    else 
        std::cout << "Sorry, that input isn't in the correct format." << std::endl;
    std::cin >> amount; // Keeps window open
}

8
请注意,例如3.14e20是一个有效的表示double类型数值的规范。祝好! - Cheers and hth. - Alf
啊,我以为可能与那有关,只是记得小学的符号,不知道double可以这样表示。谢谢。 - Fuddlebutts
1
请不要使用平台相关的技巧,如 system("pause"); 来人为地在程序末尾暂停。如果问题是“窗口突然消失”,那么可以以不同的方式运行程序,使窗口的生命周期与程序的生命周期无关。你的程序不会创建命令窗口,因此逻辑上不负责保持它的存在。 - Karl Knechtel
1
@KarlKnechtel:说得好!我认为这应该扩展到平台无关的技术,如std::cin.get()。可以复制粘贴您的消息给未来的违规者吗? - Potatoswatter
2
@AntonGolov 有时候为了正确的i18n/l10n,我们必须做这些事情,但是此时我们应该使用更复杂的工具来构建字符串而不是使用operator<<等顺序连接的方式(例如某种位置格式化工具,如boost::format)。 - Karl Knechtel
显示剩余4条评论
2个回答

2
有很多评论但没有解决方案。实际上,我也想不出一个好的解决方案。我能想到的最好的方法是安装自定义 num_get facet(这几乎肯定排除了将代码作为家庭作业解决方案提交的可能性):这是一些高级内容,我认为很少有人会考虑到这一点。
除此之外,我认为你想要数据驱动货币,即不是为每种货币设置一个代码分支,而是设置一些描述所有货币的容器(顺便说一下,欧元的复数形式是欧元)。得到的程序将看起来像这样:
#include <iostream>
#include <locale>
#include <string>
#include <tuple>
#include <map>
#include <ctype.h>

struct currency_get:
    std::num_get<char>
{
    iter_type do_get(iter_type it, iter_type end, std::ios_base&, std::ios_base::iostate& err, double& v) const
    {
        std::string input;
        for (; it != end && (*it == '.' || *it == '-' || *it == '+'
                             || isdigit(static_cast<unsigned char>(*it))); ++it)
        {
            input.push_back(*it);
        }
        errno = 0;
        if (input.empty())
        {
            err |= std::ios_base::failbit;
        }
        else
        {
            v = strtod(input.c_str(), 0);
        }

        return it;
    }
};

int main()
{
    typedef std::tuple<double, std::string, std::string> desc;
    std::map<char, desc> currencies;
    currencies['y'] = desc(0.013, "yen", "yen");
    currencies['p'] = desc(1.55, "pound", "pounds");
    currencies['e'] = desc(1.29, "euro", "euro");

    double amount(0);
    char   currency(' ');
    std::locale loc(std::locale(), new currency_get);
    std::cin.imbue(loc);

    if (std::cin >> amount >> currency)
    {
        std::map<char, desc>::const_iterator it(currencies.find(currency));
        if (it != currencies.end())
        {
            desc const& d(it->second);
            std::cout << amount << " " << (amount == 1? std::get<1>(d): std::get<2>(d)) << " is "
                      << (std::get<0>(d) * amount) << " dollar"
                      << (std::get<0>(d) * amount == 1? "": "s") << "\n";
        }
    }
    else
    {
        std::cout << "input failed\n";
    }
}

2
我认为最简单的解决方案是要求用户在数字和货币符号之间键入一个空格。 :) - Cheers and hth. - Alf

-1

以下是关于您的程序的建议:

1. 使用类似 system("pause"); 的方法暂停程序,或者如果您使用的是Visual Studio,则可以更改项目设置,使调试窗口在执行后等待您。

2. 对于下一个if语句,您应该使用else语句并用大括号括起来。这里是一个例子:

else if (unit == 'p') {
    if (amount == 1)
        std::cout << amount << " pound is $" << amount * pound_per_dollar << " dollars.\n";
    else
        std::cout << amount << " pounds is $" << amount * pound_per_dollar << " dollars.\n";
}

如果你按照这种方式做,你的最后一个else语句将会给出正确的结果。否则,除了'e'之外,你总是会得到"对不起,输入格式不正确"。事实上,这就是你程序中发生的情况。

3. 你应该为main函数的int返回类型添加一个return 0语句。

4. 你可以添加这个语句一次,而不是每次都输入std。
using namespace std;

在包含预处理器之后,您可以像这样省略包含std namespace

cout << "Please enter a amount followed by a unit (p, y, or e): ";


5. e 是一个保留字符,用于整数/双精度等数值类型。e 表示指数。在输入货币时,请在前面添加一个空格,以明确告诉 cin,该 e 不是数字输入的一部分。否则,您必须使用字符串解析输入。


请注意,如果您在main()的结尾省略了显式的return语句,则效果就好像您编写了return 0;一样。只有main()函数可以这样做。我不太喜欢这种行为,但它是标准行为(C99也支持此行为,因此C11也支持)。 - Jonathan Leffler
在早期的编程竞赛中,由于大多数评判编译器不够强大,经常会因为遗漏"return 0"而导致编译时错误。 - Atiq Rahman
你是对的,但你误解了我的意思。我并没有冒犯C语言的基本语法。我建议修改他的程序以使其能够正常运行且易于理解。如果你看一下他的程序,你就会明白了。 - Atiq Rahman
实际上,非常抱歉,我明白你的意思了(我以为你是指大括号,而不是在中间情况下显式添加 else)。 - Cactus Golov
@DietmarKühl,如果OP正在使用像Dev-C++这样的IDE,建议使用system("pause")命令;如果是Visual Studio,则建议更改项目设置以帮助调试。 - Atiq Rahman
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接