-7

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
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
amwalker
  • 345
  • 1
  • 8
  • 17
  • 2
    Take a closer look a the line `else (initial_unit != kilometers, miles);`. There's at least 3 issues with it. Think carefully about what `else ` means, what the comma operator does, and why there's a semicolon there. – Brian61354270 Apr 13 '23 at 01:51
  • 1
    [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) A debugger will show you at least two problems with this code. It will show you that the `else` isn't connected to the first `if` (for input in miles) and that the block in braces isn't the body of the `else` case. The semicolon after `(initial_unit != kilometers, miles);` should be a red flag. – jabaa Apr 13 '23 at 02:03
  • 3
    Oh, you're the one who is tutoring another student in C++ and you don't know C++, right? You received a whole lot of feedback on your other question which seems to now be deleted. At least two of us independently recommended that you attempt to actually learn C++ instead of guessing at the syntax. The [Definitive C++ Book Guide and List](https://stackoverflow.com/q/388242/1553090) has many useful links for beginners, at least one of which is a free online resource. It's okay to tell your student that you are newer to C++ than they are. It would be better for _them_ if you admitted that. – paddy Apr 13 '23 at 02:08
  • I have informed the student of my ignorance with respect to C++. There are so many assumptions made in stack overflow. I would teach the student how to use Stack Overflow as I have had much success in the past, though it seems like the C++ crowd and programming is entirely different and I would not want the student to be scared away from asking for help. – amwalker Apr 13 '23 at 02:19
  • Someone keeps closing my questions down, I have not done so. My code above runs fine without errors, so I am confused about the feedback here. At least you all have inspired me to tell the student I can no longer help them even though they have asked me to so despite my ignorance in C++ – amwalker Apr 13 '23 at 02:21
  • 2
    The slightly cold response you're getting is partly because you're shortcutting common sense and trying to run before you learn to walk. _ANY_ introductory book on C++ will cover how to write conditional statements, perform branching, _etc_. It just really looks like you're imagining how you want C++ to work, fiddling around with code until you can make it compile and then getting lost when it doesn't behave how you expect. And the second part is the tutoring thing, which is a genuine concern. I often have to fix horrendous damage to commercial code caused by poorly-trained C++ programmers. – paddy Apr 13 '23 at 02:32
  • @paddy I'm not shortcutting common sense, because I have none with regards to C++. I'm literally sharing the student's code with you, albeit I fixed a lot of the syntax errors that she originally had and apparently added my own. It would seem that the instructor for this class is expecting far too much from these students. This problem is from their first homework. – amwalker Apr 13 '23 at 02:35
  • The students are working from the book Programming: Principles and Practice Using C++ which I also have. It has been very unhelpful to me so far, largely due to the use of "std_lib_facilities.h" – amwalker Apr 13 '23 at 02:42

2 Answers2

2

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;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
1

You have gotten quite mixed up. The following code has multiple problems.

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";
}

Let's break that up to show what's actually happening:

// Output miles->km conversion
if (initial_unit == miles) {
   cout << initial_value << " " << initial_unit << " "<< "is" << " " << conversion_factor << "\n" << "km";
}

// This condition is unrelated to the first
if (initial_unit == kilometers) {
   cout << initial_value << " " << initial_unit << " "<< "is" << " " << conversion_factor2 << "\n" << "mi";
} else {
    initial_unit != kilometers;  // unused inequality test
    miles;                       // unused result of comma operator
}

// This is always executed
cout << "Unknown unit, please try again";

The correct chain of conditionals is:

if (initial_unit == miles) {
   cout << initial_value << " " << initial_unit << " is " << conversion_factor << "km\n";
}
else if (initial_unit == kilometers) {
   cout << initial_value << " " << initial_unit << " is " << conversion_factor2 << "mi\n";
}
else {
   cout << "Unknown unit, please try again\n";
}
paddy
  • 60,864
  • 6
  • 61
  • 103