Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Taking char 'e' as input and comparing

Tags:

c++

OK, so I am doing an exercise in a book, converting different types of money to dollars. For some reason when I type in 'e' as input for a char variable and compare it to 'e' in an if statement the comparison doesnt work, however if I replace it with another letter it will work fine. What's the deal? Heres the code:

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
}
like image 859
Fuddlebutts Avatar asked Nov 13 '22 12:11

Fuddlebutts


1 Answers

There are lots of comments but no solution. In fact, I couldn't come up with a good solution, either. The best I could think of is to install a custom num_get facet (this alone almost certainly rules the code out as being suitable for being handed in as a homework solution): this is somewhat advanced stuff and I don't think many people would ever think of this.

Other than this, I'd think that you want to data-drive the currencies, i.e. instead of having a code branch for each currency, you want to set up some sort of container describing all currencies (BTW, the plural of Euro is Euro). The resulting program would look something like this:

#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";
    }
}
like image 87
Dietmar Kühl Avatar answered Dec 28 '22 03:12

Dietmar Kühl