Search code examples
c++if-statementcincout

Trouble with multiple prompts in C++


How do I rewrite the following code such that each output has it's own prompt (see desired outcome) - g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::string;

int main() {

    cout << "Enter a numeric value followed by a unit abbreviation (km,mi): ";
    double initial_value;
    string initial_unit;
    cin >> initial_value >> initial_unit; 

    double conversion_factor = {initial_value *1.609};
    double conversion_factor2 = {initial_value /1.609};
    std::string miles = "mi";
    std::string kilometers = "km";

    if (initial_unit == miles) {
       cout << initial_value << " " << initial_unit << " "<< "is" << " " << conversion_factor << "\n" << "km";
    }
    if (initial_unit == kilometers) {
       cout << initial_value << " " << initial_unit << " "<< "is" << " " << conversion_factor2 << "\n" << "mi";
    }
    else (initial_unit != kilometers, miles);
    {
       cout << "Unknown unit, please try again";
    }

    return 0;
}

Outcome I am getting:

Enter a numeric value followed by a unit abbreviation (km,mi): 10 mi
10 mi is 16.09
kmUnknown unit, please try again

Example of desired outcome:

Enter a numeric value followed by a unit abbreviation (km,mi): 
10 mi
10 mi is 16.09 km  
16.09 km
16.09 km is 10 mi  
20000 leagues
Unknown unit, please try again  
0.5 mi
0.5 mi is 0.8045 km

Solution

  • The statement else (initial_unit != kilometers, miles); is completely wrong.

    For one thing, the ; should not be there. That is causing your code to output the Unknown unit message regardless of what initial_unit is actually set to.

    But more importantly, you can't compare a single value against a comma-separated list of values like you are trying to do. Due to the comma operator and operator precedence, the expression initial_unit != kilometers, miles would be interpreted as (initial_unit != kilometers), miles and thus the result of the expression would be miles regardless of what initial_unit is actually set to.

    You have to compare each value individually, like this:

    else if ((initial_unit != kilometers) && (initial_unit != miles))
    

    But, you already compared initial_unit against kilometers and miles before that statement, so there is no need to compare them again. The statement should be just an else by itself, eg:

    if (initial_unit == miles) {
       ...
    }
    else if (initial_unit == kilometers) { // <-- you forgot the 'else' here
       ...
    }
    else { // <-- everything else!
       ...
    }
    

    Now, that being said, to do what you are asking, you need to run a loop, where each iteration prompts the user for new input, eg:

    #include <iostream>
    #include <string>
    
    using std::cin;
    using std::cout;
    using std::string;
    
    int main() {
    
        const std::string miles = "mi";
        const std::string kilometers = "km";
    
        cout << "Enter a numeric value followed by a unit abbreviation (km,mi):\n";
    
        double value;
        string unit;
    
        while (cin >> value >> unit) {
    
            if (unit == miles) {
                cout << value << " " << unit << " is " << (value * 1.609) << " " << kilometers << '\n';
            }
            else if (unit == kilometers) {
                cout << value << " " << unit << " is " << (value / 1.609) << miles << '\n';
            }
            else {
                cout << "Unknown unit, please try again\n";
            }
        }
    
        return 0;
    }