Need help with assignment

Mar 14, 2021 at 10:24pm
I have a homework assignment but need help with it. It goes
Ask the user for his/her weight (in pounds) on Earth
Ask the user for the name of a celestial body (list given below)
The program must output the weight of the user in that celestial body as follows: "your weight of (user weight) lbs. in (celestial body) is = (weight on that celestial body)"
Output an error message if the user doesn’t type a correct planet name.
The prompt and the error message should make it clear to the user how a planet name must be entered.
The output should be labeled clearly and formatted neatly.
The output must be display with 2 decimal points.
Must use a menu system
So far I have this but one of the biggest problems I'm having is the menu system. How in the world am I to do that? We have never gone over that in class but he gave us a rubric of another menu and idk how to do it tbh. I'm having a headache trying to figure this out. I'll add the menu in the comments. Any help is appreciated on how I can fix my code as well. Thank you everyone.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  #include <iostream>
#include <string>
 
using namespace std;
int main()
{
    float weight;
    string planet;
 
    const double Mercury = 0.4155;
    const double Venus = 0.8975;
    const double Earth = 1.0000;
    const double Moon = 0.1660;
    const double Mars = 0.3507;
    const double Jupiter = 2.5374;
    const double Saturn = 1.0677;
    const double Uranus = 0.8947;
    const double Neptune = 1.1794;
    const double Pluto = 0.0899;
 
    cout << "Enter your weight in pounds" <<endl;
    cin >> weight;
    cout << "Enter a planet name: Mercury, Venus, Earth, Moon, Mars, Jupiter,"
    " Saturn, Uranus, Neptune, Pluto. " << endl;
    cin >> planet;
    
    
    {
    if (planet == "Mercury")
        cout<< "Your weight on Mercury is " << weight*Mercury <<"." <<endl;
    if (planet == "Venus")
        cout<< "Your weight on Venus is " << weight*Venus << "." << endl;
    if (planet == "Earth")
        cout<< "Your weight on Earth is " << weight*Earth << "." << endl;
    if (planet == "Moon")
        cout<< "Your weight on the Moon is " << weight*Moon << "." << endl;
    if (planet == "Mars")
        cout<< "Your weight on Mars is " << weight*Mars << "." << endl;
    if (planet == "Jupiter")
        cout<< "Your weight on Jupiter is " << weight*Jupiter << "." <<endl;
    if (planet == "Saturn")
        cout<< "Your weight on Saturn is " << weight*Saturn << "." << endl;
    if (planet == "Uranus")
        cout<< "Your weight on Uranus is " << weight*Uranus << "." << endl;
    if (planet == "Neptune")
        cout<< "Your weight on Neptune is "<< weight*Neptune << "." << endl;
     if (planet == "Pluto")
        cout<< "Your weight on Pluto is " << weight*Pluto << "." << endl;
    else 
        cout << "Incorrect name of celestial body. The name must be entered as;"
        " Mercury, Venus, Earth, Moon, Mars, Jupiter, Saturn, Uranus, Neptune,"
        " or Pluto." << endl;
        
}
    return 0;
}
Mar 14, 2021 at 10:26pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
 //***
// PROGRAM NAME: simpleMenu.cpp
// DATE:         6 May 2019
// VERSION:      1.0
// PROPGRAMMER:   Name
// DESCRIPTION:  This program demonstrates implementation
// of a simple menu system using the do-while loop.
//***
#include<iostream>
#include <string>
using namespace std;

// Function prototypes
void runApplication();
void displayMenu();
void getUserChoice();
void executeCommand();
void pressEnterToContinue();
void clearConsole();


// Global Constants
int const EXIT = 0;
int const MAX_STRING_LENGTH = 100;

// Global Variables
int userChoice = EXIT;

int main() {
    runApplication();
    return 0;
} // End of method main

/*
* METHOD NAME:  runApplication()
* PARAMETER(S): none
* RETURN TYPE:  void
* VERSION:      1.0
* DATE:         6 May 2019
* PROGRAMMER:   Name
* DESCRIPTION:  This method displays the menu, get the
* user choice and execute a valid command. If user exits,
* it clears the console
*/
void runApplication() {
    do {
        clearConsole();
        displayMenu();
        getUserChoice();
        executeCommand();
    } while (userChoice != EXIT);
} // End of method runApplication

/*
* METHOD NAME:  displayMenu()
* PARAMETER(S): none
* RETURN TYPE:  void
* VERSION:      1.0
* DATE:         6 May 2019
* DESCRIPTION:  This method display a simple menu,
* it gets the input from the user, and passess the
* user input to the method that executes the selected choice.
*/
void displayMenu() {
    cout << "  ___________________________________"  << endl;
    cout << " |             SIMPLE MENU           |" << endl;
    cout << " |SELECT ONE OF THE FOLLOWING CHOICES|" << endl;
    cout << " |___________________________________|" << endl;
    cout << " |          0. Exit Program          |" << endl;
    cout << " |          1. Calculate the weight  |" << endl;
    cout << " |___________________________________|" << endl;
    cout << "    Enter your choice: ";
}//End of method displayMenu()

/*
* METHOD NAME:  getUserChoice()
* PARAMETER(S): none
* RETURN TYPE:  void
* VERSION:      1.0
* DATE:         6 May 2019
* DESCRIPTION:  This method gets the choice from the user
* as an "int" and stores the value in the global variable
* userChoice.
*/
void getUserChoice() {
    cin >> userChoice; // Save the user input in the global variable
    cout << endl;
} // End of method getUserChoice

/*
* METHOD NAME:  executeCommand()
* PARAMETER(S): none
* RETURN TYPE:  void
* VERSION:      1.0
* DATE:         6 May 2019
* DESCRIPTION:  This method executes the command that matches
* a one of the commands in this method.
*/
void executeCommand() {
    switch (userChoice) {
        case 0:
	      cout << "Exiting Program" << endl;
	      cout << "Exiting Program" << endl;
	      break;
        case 1:
	      cout << "Enter name of planet: " << endl;
	      cout << "Enter your weight in pounds: " << endl;
	      break;
     	default:
	      cout << "Invalid Choice, Try Again" << endl;
	      cout << "Invalid Choice, Try Again" << endl;
	      break;
    } // End of switch()
    cout << endl;
    pressEnterToContinue();
} // End of method executeCommand

/*
* METHOD NAME:  pressEnterToContinue()
* PARAMETER(S): none
* RETURN TYPE:  void
* VERSION:      1.0
* DATE:         6 May 2019
* DESCRIPTION:  This method implements the "Press Enter"
* to continue task, using cin and .ignore method.
*/
void pressEnterToContinue()
{
    char key;
    cin.clear(); //clears the error flag on cin
                 //so that future I/O operations will work correctly.
    cin.ignore(MAX_STRING_LENGTH, '\n'); // ignore until <Enter> key
    cout << "Press <Enter> to continue . . .";
    key = cin.get();
} // End of method pressEnterToContinue

/*
* METHOD NAME:  clearConsole()
* PARAMETER(S): none
* RETURN TYPE:  void
* VERSION:      1.0
* DATE:         6 May 2019
* DESCRIPTION:  This method clears the screen console
* using the system() method call.
*/
void clearConsole()
{
    system("clear"); // use "cls" for windows, "clear" for linux

} // End of method clearConsole 
Mar 15, 2021 at 12:15am
Hello av16352,

Just a note for your first code: the {}s at lines 28 and 54 are not needed. The is no real advantage to create a block for the if statements. And if you should define a variable inside that block it is local to the t block and will be destroyed at the closing }.

Next the variables defined as "constant". If you are using a compiler set to the C 2011 standards or later consider using constexpr instead of const. Also it helps to write the variable of a constant in all capital letters. It helps to avoid confusion with a variable name or a string.

In your second code for your menu consider this:
1
2
3
4
5
6
7
8
9
10
    cout <<
        "\n"
        "  ___________________________________\n"
        " |             SIMPLE MENU           |\n"
        " |SELECT ONE OF THE FOLLOWING CHOICES|\n"
        " |___________________________________|\n"
        " |          0. Exit Program          |\n"
        " |          1. Calculate the weight  |\n"
        " |___________________________________|\n"
        "    Enter your choice: ";

There is no need for a "cout" statement for every line. As written it may look like 9 lines, but it is considered 1 very large string of 296 characters in the end. The very last character is a (\0) to mark the end of the string.

In most menus "Exit" is usually the last choice. This method makes the menu easier to change and work with. Also you might consider putting something above the menu to explain what the program does. Easy enough to add a first "cout" for this.

At the beginning of your program you have:
1
2
3
4
5
6
// Global Constants
int const EXIT = 0;
int const MAX_STRING_LENGTH = 100;

// Global Variables
int userChoice = EXIT;

The constant variables are fine, but consider this:
1
2
3
// Global Constants
constexpr int  EXIT{};
constexpr MAX_STRING_LENGTH{ 100 };

The {}s are available from C++11 on and much quicker to type than " = 0". Empty {}s the compiler will choose the best form of (0)zero based on the variables type.

"userChoice" may be nice as a global variable, but should be avoided. Since the entire program has access to this variable it can be hard to track down where what line of code changed this to something that you do not want. It is better to define this variable in "main" or the "runApplication" function and pass it to any other function that may need it or use another functions return value to get its value.

"getUserChoice" is nice and has potential, but as is you do not need a function just for input. If you expand the function to check for a non numeric input and make sure the number entered is in a valid range then only return valid input the function would be useful. This would also cause a change to the "runApplication" function".

In the "pressEnterToContinue" function consider using:
 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. 

In the past it has been said that this is the more portable way of clearing the input buffer that any compiler and header files can use. Your method is fine and will work, but "100" may not be enough for the 1st parameter. Most times I see "1000" used.

Over all the code looks like a good start, but has a way to go.

Andy
Mar 15, 2021 at 2:08am
Hello Andy,

Let's pretend I never posted the second code. For the menu so far I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <string>

using namespace std;

void userInput()
{
    float weight;
    string planet;
    const float Mercury = 0.4155;
    const float Venus = 0.8975;
    const float Earth = 1.0000;
    const float Moon = 0.1660;
    const float Mars = 0.3507;
    const float Jupiter = 2.5374;
    const float Saturn = 1.0677;
    const float Uranus = 0.8947;
    const float Neptune = 1.1794;
    const float Pluto = 0.0899;
    
    cout << "Please enter your weight in pounds: " << endl;
    cin >> weight;
    cout << "Enter a planet name: : Mercury, Venus, Earth, Moon, Mars, Jupiter,"
    " Saturn, Uranus, Neptune, Pluto. " << endl;
    cin >> planet;
    
}

int main()
{
    int choice;
    do
    {
    cout << "0: Quit Program" << endl;
    cout << "1: Calculate the weight" << endl;
    cin >> choice;
    
    switch(choice)
        {
        case 0: cout << "Exiting Program" << endl;
              break;
        case 1: userInput();
              break;
        }
    
    
    }
    while( choice != 0 );
}


How do I go about adding the rest of my code in? For example if someone enters something wrong and calculating the weight.
Mar 15, 2021 at 2:12am
Hello av16352,

Consider this for your program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include<iostream>
#include <string>

#include <chrono>  // <--- Added.
#include <thread>  // <--- Added.

using namespace std;  // <--- Best not to use.

// Function prototypes
void runApplication();
void displayMenu();
int getUserChoice();                  // <--- Changed.
void executeCommand(int userChoice);  // <--- Changed.
void pressEnterToContinue();
void clearConsole();


// Global Constants
constexpr int EXIT{ 2 };
constexpr int MAX_STRING_LENGTH{ 100 };
constexpr double MERCURY{ 0.4155 };  // <--- Start of planets.

void runApplication()
{
    int userChoice{};

    do
    {
        clearConsole();

        displayMenu();

        userChoice = getUserChoice();

        executeCommand(userChoice);
    } while (userChoice != EXIT);
} // End of method runApplication

void displayMenu()
{
    std::cout <<
        "\n This program will calculate your weight on different planets.\n\n";

    cout <<
        "  ___________________________________\n"
        " |             SIMPLE MENU           |\n"
        " |SELECT ONE OF THE FOLLOWING CHOICES|\n"
        " |___________________________________|\n"
        " |          1. Calculate the weight  |\n"
        " |          2. Exit Program          |\n"
        " |___________________________________|\n"
        "    Enter your choice: ";
}//End of method displayMenu()

int getUserChoice()
{
    constexpr int MINCHOICE{ 1 }, MAXCHOICE{ 2 };

    int userChoice{};

    while (!(std::cin >> userChoice) || userChoice < MINCHOICE || userChoice > MAXCHOICE) // Save the user input in the global variable
    {
        if (!std::cin)
        {
            std::cerr << "\n     Invalid Entry! Must be a number.\n\n";

            std::cin.clear();  // <--- Resets the state bits.
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. Clears the buffer.
        }
        else if (userChoice < MINCHOICE || userChoice > MAXCHOICE)
        {
            std::cerr << "\n     Invalid choice! try again.\n\n";
        }

        std::this_thread::sleep_for(std::chrono::seconds(3));  // Requires header files "chrono" and "thread".
        
        clearConsole();

        displayMenu();
    }


    return userChoice;
} // End of method getUserChoice

void executeCommand(int userChoice)
{
    switch (userChoice)
    {
        case 1:
            // <--- Needs to call a function. The next 2 lines should be in the function.
            cout << "Enter name of planet: ";
            cout << "Enter your weight in pounds: ";
            break;
        case 2:
            cout << "Exiting Program\n";  // <--- Only need 1 here.
            //cout << "Exiting Program" << endl;
            break;
        //default:
        //    cout << "Invalid Choice, Try Again\n";
        //    //cout << "Invalid Choice, Try Again" << endl;
            break;
    } // End of switch()

    cout << '\n';

    pressEnterToContinue();
} // End of method executeCommand

void pressEnterToContinue()
{
    char key;
    cin.clear(); //clears the error flag on cin
                 //so that future I/O operations will work correctly.
    cin.ignore(MAX_STRING_LENGTH, '\n'); // ignore until <Enter> key
    //std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

    cout << "Press <Enter> to continue . . .";
    cin.get();
} // End of method pressEnterToContinue

I have not changed everything yet, but prefer using the new line (\n) over the function call "endl". Usually the (\n) is sufficient, but sometimes you may still need an "std::endl" at the end of a "std::cout". Something that works for you is if a "cout" is followed be a "cin" the "cin" will flush the output buffer before any input is allowed.

I put int userChoice{}; in the "runApplication" function because that is where it is used. Also it is always a good idea to initialize your variables when defined.

The "getUserChoice" is more involved than what you started with, but what you have here is that cin >> userChoice; is formatted input and is expecting a whole number to be entered. Entering something that is not a numeric value will cause "std::cin" to fail and be unusable the rest of the program until fixed. That is done in the if statement.

If you do not or can not use line 75 you will need something to cause a delay before the screen is cleared.

I think you can understand what I did in the "executeCommand" function.

In the "pressEnterToContinue" function you should not need the "clear()". Either 1 of the ignore statements may not be needed. This is 1 that you will have to decide on as you test your program. At the moment it is needed.

As noted in case 1 you need a function to display the planet names as they are to be entered, get user input and check that the input is spelled correctly. Print an error message if it is not.
Not worked on yet just thinking it out you could define an array of "std::string"s with the planet names then use a for loop to check if the name entered matches one of the strings in the array. Defining the loop iterator outside the for loop you can use it value to drive a switch to figure the different weights.

Until I go back and check the directions that is what I can remember for now.

That should give you something to work on.

Andy
Mar 15, 2021 at 2:25am
Hello av16352,

I did not see your reply until I posted and refreshed.

Actually your first code is better because you used "double"s that are now "float"s. For a floating point number it is better to prefer using a "double" over a "float" unless there is a good reason to use "float".

I have worked with your second code because it is a better layout than the first, but there are parts of the first code that can be combined into the second code to make it work.

Before you try to fix this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
    int choice;
    do
    {
    cout << "0: Quit Program" << endl;
    cout << "1: Calculate the weight" << endl;
    cin >> choice;
    
    switch(choice)
        {
        case 0: cout << "Exiting Program" << endl;
              break;
        case 1: userInput();
              break;
        }
    }
    while( choice != 0 );
}

Look over what I posted and see if that work better for you.

Watch your indenting, it really helps on both sides of the post.

I can work with whatever version you choose. I just need to know what you are going to use.

Andy
Last edited on Mar 15, 2021 at 2:26am
Mar 15, 2021 at 2:37am
Andy,

I plan on using the third version I posted rather than my first two.

As far as fixing the code that you just commented, did you mean my indenting or am I missing something? So far I fixed the indenting.
Edit: Also changed it to double

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>

using namespace std;

void userInput()
{
    double weight;
    string planet;
    const double Mercury = 0.4155;
    const double Venus = 0.8975;
    const double Earth = 1.0000;
    const double Moon = 0.1660;
    const double Mars = 0.3507;
    const double Jupiter = 2.5374;
    const double Saturn = 1.0677;
    const double Uranus = 0.8947;
    const double Neptune = 1.1794;
    const double Pluto = 0.0899;
    
    cout << "Please enter your weight in pounds: " << endl;
    cin >> weight;
    cout << "Enter a planet name: : Mercury, Venus, Earth, Moon, Mars, Jupiter,"
    " Saturn, Uranus, Neptune, Pluto. " << endl;
    cin >> planet;
    
    if (planet == "Mercury")
        cout<< "Your weight on Mercury is " << weight*Mercury <<"." <<endl;
    if (planet == "Venus")
        cout<< "Your weight on Venus is " << weight*Venus << "." << endl;
    if (planet == "Earth")
        cout<< "Your weight on Earth is " << weight*Earth << "." << endl;
    if (planet == "Moon")
        cout<< "Your weight on the Moon is " << weight*Moon << "." << endl;
    if (planet == "Mars")
        cout<< "Your weight on Mars is " << weight*Mars << "." << endl;
    if (planet == "Jupiter")
        cout<< "Your weight on Jupiter is " << weight*Jupiter << "." <<endl;
    if (planet == "Saturn")
        cout<< "Your weight on Saturn is " << weight*Saturn << "." << endl;
    if (planet == "Uranus")
        cout<< "Your weight on Uranus is " << weight*Uranus << "." << endl;
    if (planet == "Neptune")
        cout<< "Your weight on Neptune is "<< weight*Neptune << "." << endl;
     if (planet == "Pluto")
        cout<< "Your weight on Pluto is " << weight*Pluto << "." << endl;
    
}

int main()
{
    int choice;
    do
    {
    cout << "0: Quit Program" << endl;
    cout << "1: Calculate the weight" << endl;
    cin >> choice;
    
    switch(choice)
    {
    case 0: cout << "Exiting Program" << endl;
         break;
    case 1: userInput();
         break;
    }
    
    
    }
    while( choice != 0 );
}


Now I need help when somebody misspells a planet name. Do I do the else statement?
Last edited on Mar 15, 2021 at 2:47am
Mar 15, 2021 at 3:26am
Hello av16352,

Yes I meant the indenting in your last bit of code I posted. lines 6 - 8 and lines 12 - 16. Also your {} on the switch need to back up a tab or 4 spaces.

In the function I would consider using a switch. Or I would make the if statements if\else if statements. This way you will not have to check every if statement when you find a match early.

The rest I will have to work on in the morning.

Andy
Mar 15, 2021 at 4:24am
Andy,

If you would be kind enough to go double check my code and tell me if I missed something or need better indenting please let me know. However, I think I have finished and this is the final product.

Edit; My professor recently showed us global variables and also wanted us to do global variables which is why I have global variables.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

double weight;
string planet;
double Mercury = 0.4155;
double Venus = 0.8975;
double Earth = 1.0000;
double Moon = 0.1660;
double Mars = 0.3507;
double Jupiter = 2.5374;
double Saturn = 1.0677;
double Uranus = 0.8947;
double Neptune = 1.1794;
double Pluto = 0.0899;

void userInput()
{
    cout << "Please enter your weight in pounds: " << endl;
    cin >> weight;
    cout << "Enter the name of a celestial body: " << endl;
    cin >> planet;
}    
void calculatingWeight()
{
    cout << fixed << showpoint << setprecision(2);

    if (planet == "Mercury")
        cout<< "Your weight: " << weight << " on Mercury is: "  
        << weight*Mercury <<endl;
    
    else if (planet == "Venus")
        cout<< "Your weight: " << weight << " on Venus is: " 
        << weight*Venus << endl;
        
    else if (planet == "Earth")
        cout<< "Your weight: " << weight << " on Earth is: " 
        << weight*Earth << endl;
    
    else if (planet == "Moon")
        cout<< "Your weight: " << weight << " on the Moon is: " 
        << weight*Moon << endl;
    
    else if (planet == "Mars")
        cout<< "Your weight: " << weight << " on Mars is: " 
        << weight*Venus << endl;
    
    else if (planet == "Jupiter")
        cout<< "Your weight: " << weight << " on Jupiter is: " 
        << weight*Jupiter << endl;
    
    else if (planet == "Saturn")
        cout<< "Your weight: " << weight << " on Saturn is: " 
        << weight*Saturn << endl;
    
    else if (planet == "Uranus")
        cout<< "Your weight: " << weight << " on Uranus is: " 
        << weight*Uranus << endl;
    
    else if (planet == "Neptune")
        cout<< "Your weight: " << weight << " on Neptune is: " 
        << weight*Neptune << endl;
    
    else if (planet == "Pluto")
        cout<< "Your weight: " << weight << " on Pluto is: " 
        << weight*Pluto << endl;
    else
    {
        cout << "Incorrect, the celestial body name must be typed as: " 
        "Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune "
        "Pluto, or Moon. " << endl;
    }
    
}

int main()
{
    int choice;
    do
    {
    cout << "  ___________________________________"  << endl;
    cout << " |This program calculates the weight |" << endl;
    cout << " |of a person in one of the celestial|" << endl;
    cout << " |bodies: Mercury, Venus, Earth, Mars|" << endl;
    cout << " |Jupiter, Saturn, Uranus, Neptune,  |" << endl;
    cout << " |Pluto, and Moon.                   |" << endl;
    cout << " |-----------------------------------|" << endl;
    cout << " |                  MENU             |" << endl;
    cout << " |      0: Quit Program              |" << endl;
    cout << " |      1: Calculate the weight      |" << endl;
    cout << " |-----------------------------------|" << endl;
    cout << " |      Enter your choice:           |" << endl;
    cin >> choice;
    
    switch(choice)
    {
    case 0: cout << "Exiting Program" << endl;
         break;
    case 1: userInput();
            calculatingWeight();
         break;
    default: cout << "Invalid choice, try again!" << endl;
    }
    
    }
    while( choice != 0 );
    
    return 0;
}
Last edited on Mar 15, 2021 at 4:33am
Mar 15, 2021 at 12:19pm
Probably a bit advanced for your current knowledge, but something to think about:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
#include <limits>
#include <cctype>

struct Planets {
	std::string name;
	double convert {};
};

const Planets planets[] {{"mercury", 0.4155}, {"venus", 0.8975}, {"earth", 1.0}, {"moon", 0.1660}, {"mars", 0.3507},
	{"jupiter", 2.5374}, {"saturn", 1.0677}, {"uranus", 0.8947}, {"neptune", 1.1794}, {"pluto", 0.0899}};

double getNum(const std::string& prm)
{
	double i {};

	while ((std::cout << prm) && (!(std::cin >> i) || std::cin.peek() != '\n')) {
		std::cout << "Not a number\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return i;
}

int getInt(const std::string& prm)
{
	int i {};

	while ((std::cout << prm) && (!(std::cin >> i) || std::cin.peek() != '\n')) {
		std::cout << "Not an integer\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return i;
}

double calculatingWeight(const std::string& planet, double weight)
{
	if (const auto p {std::find_if(std::begin(planets), std::end(planets), [&planet](const auto& p) {return p.name == planet; })}; p != std::end(planets))
		return weight * p->convert;

	return -1.0;
}

void lc(std::string& str)
{
	for (auto& ch : str)
		ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
}

void doCalc()
{
	const auto weight {getNum("\nEnter weight in pounds: ")};
	std::string planet;

	std::cout << "Enter the name of a celestial body: ";
	std::cin >> planet;

	lc(planet);

	if (const auto planweight {calculatingWeight(planet, weight)}; planweight > 0)
		std::cout << std::fixed << std::showpoint << std::setprecision(2) << "The weight on " << planet << " is " << planweight << '\n';
	else
		std::cout << "Invalid planet\n";
}

int main()
{
	int choice {};

	do {
		std::cout << "  ___________________________________\n";
		std::cout << " |This program calculates the weight |\n";
		std::cout << " |of a person in one of the celestial|\n";
		std::cout << " |bodies: Mercury, Venus, Earth, Mars|\n";
		std::cout << " |Jupiter, Saturn, Uranus, Neptune,  |\n";
		std::cout << " |Pluto, and Moon.                   |\n";
		std::cout << " |-----------------------------------|\n";
		std::cout << "\n         MENU\n";
		std::cout << " 0: Quit Program\n";
		std::cout << " 1: Calculate the weight\n";

		switch (choice = getInt("\nEnter choice: ")) {
			case 0:
				std::cout << "Exiting Program\n";
				break;

			case 1:
				doCalc();
				break;

			default:
				std::cout << "Invalid choice, try again!\n";
				break;
		}
	} while (choice);
}


@ av16352, initialised variables that don't have their values changed are marked as const to ensure this. Thus:

1
2
3
4
5
6
7
8
9
10
const double Mercury = 0.4155;
const double Venus = 0.8975;
const double Earth = 1.0000;
const double Moon = 0.1660;
const double Mars = 0.3507;
const double Jupiter = 2.5374;
const double Saturn = 1.0677;
const double Uranus = 0.8947;
const double Neptune = 1.1794;
const double Pluto = 0.0899;


Irrespective what your professor wants, it's a BAD idea to use non-const global variables. Except when explicitly told to use for an exercise, don't use them!

I don't know what your professor has taught re numeric input, but your code has problems if a non-numeric value is entered when a number is expected. Try it!
Last edited on Mar 15, 2021 at 5:38pm
Mar 15, 2021 at 12:58pm
Hello av16352,

Overall The program works. Good for learning, but not the best way to code it.

Technically speaking and somewhat trivial the "#include"s it makes no difference in which order they are in. Although I have found that:
1
2
3
#include <iostream>
#include <iomanip>
#include <string> 

Tends to be helpful. "iomanip"only works with "iostream", so I keep them together. After that I found that alphabetical order tends to help when you forget something.

Lines 7 and 8 are not the best idea to have something like these variables as global variables. Any line of code the follows can change their values and it becomes difficult to track down where it was changed when it should not have been.

Lines 9 - 18 are fine as global variables, but these should be defined as constant variables. As:
1
2
constexpr double MERCURY{ 0.4155 };
constexpr double VENUS{ 0.8975 };

Also you should be trying to learn and use what became available in the C++ 2011 standards like: "constexpr" and the {}s known as the uniform initializer. These will take you farther than what you have done although technically correct and legal code they are old.

In the function "userInput" a blank line between lines 23 and 24 really help make the code more readable and this is what you should strive for. Also this function is where I would check for valid user input of the planet name and not wait until the next function to check this. It may be my way of thinking, but I think you should validate input when it is input and not wait until later.

Next would be to deal with an invalid weight. The formatted input of cin >> weight; is expecting a numeric value and a whole number at that. Anything that is not a numeric value will cause "cin" to be put in a failed state and it will become unusable the rest of the program. I also realize that in the utopia of school nobody makes mistakes, so checking for errors is not necessary yet.

In the "calculatingWeight" function I did this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void calculatingWeight()
{
    double planetWeight{};

    if (planet == "Mercury")
        //cout << "Your weight: " << weight << " on Mercury is: "
        //<< weight * MERCURY << endl;
        planetWeight = weight * MERCURY;

//  The rest of the else if statements.
//  After the else statement, which you could do without.

    cout << "\nYour weight of: " << weight << " lbs on " << planet << " is: " << planetWeight << " lbs.\n\n";

This way you only need 1 "cout" statement. You already have a value for "weight" and "planet", which are global variables and the function already has access to them. So you can use what you have instead of all the mostly duplicate "cout" statements. This will reduce your code in the function to just what you need making better use of the language and variables that yo have.

"main" is OK and will work.

If you are expecting to get a job in programing with code like:
1
2
3
4
5
6
7
8
9
10
11
12
cout << "  ___________________________________" << endl;
cout << " |This program calculates the weight |" << endl;
cout << " |of a person in one of the celestial|" << endl;
cout << " |bodies: Mercury, Venus, Earth, Mars|" << endl;
cout << " |Jupiter, Saturn, Uranus, Neptune,  |" << endl;
cout << " |Pluto, and Moon.                   |" << endl;
cout << " |-----------------------------------|" << endl;
cout << " |                  MENU             |" << endl;
cout << " |      0: Quit Program              |" << endl;
cout << " |      1: Calculate the weight      |" << endl;
cout << " |-----------------------------------|" << endl;
cout << " |      Enter your choice: ";

You may have a longer weight than others.

This is more efficient and makes better use of the language:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
cout <<
    "\n"
    "  ___________________________________"
    " |This program calculates the weight |\n"
    " |of a person in one of the celestial|\n"
    " |bodies: Mercury, Venus, Earth, Mars|\n"
    " |Jupiter, Saturn, Uranus, Neptune,  |\n"
    " |Pluto, and Moon.                   |\n"
    " |-----------------------------------|\n"
    " |                  MENU             |\n"
    " |      0: Quit Program              |\n"
    " |      1: Calculate the weight      |\n"
    " |-----------------------------------|\n"
    " |      Enter your choice: ";

This may look like 13 lines, but in the end it is considered just 1 string. So you cave 1 "cout", 1 string and not "\n" or "endl" at the end. This puts your input on the same line as the prompt Without any extra coding. Also the "cin" will flush the buffer before any input is taken, so everything will print to the screen before andy input is allowed.

Andy
Mar 15, 2021 at 5:58pm
@seeplus Yes, I'm assuming those are arrays? While that does look better we have not learned that yet. We will learn it though next class. I realized my mistake with taking away the constants but I put them in once again. Global variables do suck indeed. We have not learned re-numeric input and I am aware than when someone enters a char instead of a number in cin that it has problems. However, he gave us his version of the program so that we can run it in terminal and show us what it looks like. He too has the same issue as me when I enter a non-numeric value so I'm going to leave that alone :p. I will work on it after I submit it and teach myself re-numeric input. Thank you for your feedback!

@Handy Andy I fixed my libraries and put them alphabetically. I switched the planets back to constants. We learned constants but not constexpr, hopefully we do soon. I went back and put a space in between lines 23 and 24. Seeplus mentioned the cin >> weight; which I addressed. I tried to do what you did in the calculatingWeight section but I was having issues with this part:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  void calculatingWeight()
{
    double planetWeight;
    
    cout << fixed << showpoint << setprecision(2);

    if (planet == "Mercury")
        planetWeight = weight * MERCURY;
    
    else if (planet == "Venus")
        planetWeight = weight * VENUS;
        
    else if (planet == "Earth")
        planetWeight = weight * EARTH;
    
    else if (planet == "Moon")
        planetWeight = weight * MOON;
    
    else if (planet == "Mars")
        planetWeight = weight * MARS;
    
    else if (planet == "Jupiter")
        planetWeight = weight * JUPITER;
    
    else if (planet == "Saturn")
        planetWeight = weight * SATURN;
    
    else if (planet == "Uranus")
        planetWeight = weight * URANUS;
    
    else if (planet == "Neptune")
        planetWeight = weight * NEPTUNE;
    
    else if (planet == "Pluto")
        planetWeight = weight * PLUTO;
    else
    {
        cout << "Incorrect, the celestial body name must be typed as: " 
        "Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune "
        "Pluto, or Moon. " << endl;
    }
        cout << "Your weight of: " << weight << " lbs on " << planet << " is: " 
        << planetWeight << " lbs." << endl;
}


It works perfect when the user enters the right planet name but when someone enters the wrong planet name the error message pops up that if I have in else along with the next cout statement
"Your weight of: weight on kfkrfm is 0.00 lbs."
I know that anything after the else statement will print regardless but how do I go about fixing that? I only want it to print when the user enters the right planet name not when they get it wrong.

I went ahead and added the new line sequence character \n for the menu part. We haven't learned that but it was simple enough for me to explain it in notes so he won't deduct points for something he hasn't taught us yet.

So far I have this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
 #include <iostream>
#include <iomanip>
#include <string>

using namespace std;

double weight;
string planet;

const double MERCURY = 0.4155;
const double VENUS = 0.8975;
const double EARTH = 1.0000;
const double MOON = 0.1660;
const double MARS = 0.3507;
const double JUPITER = 2.5374;
const double SATURN = 1.0677;
const double URANUS = 0.8947;
const double NEPTUNE = 1.1794;
const double PLUTO = 0.0899;

void userInput()
{
    
    cout << "Please enter your weight in pounds: " << endl;
    cin >> weight;
    
    cout << "Enter the name of a celestial body: " << endl;
    cin >> planet;
}    
void calculatingWeight()
{
    double planetWeight;
    
    cout << fixed << showpoint << setprecision(2);

    if (planet == "Mercury")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * MERCURY << " lbs." << endl;
    
    else if (planet == "Venus")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * VENUS << " lbs." << endl;
        
    else if (planet == "Earth")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * EARTH << " lbs." << endl;
    
    else if (planet == "Moon")
        cout << "Your weight: " << weight << " lbs on the " << planet << " is: " 
        << weight * MOON << " lbs." << endl;
    
    else if (planet == "Mars")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * MARS << " lbs." << endl;
    
    else if (planet == "Jupiter")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * JUPITER << " lbs." << endl;
    
    else if (planet == "Saturn")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * SATURN << " lbs." << endl;
    
    else if (planet == "Uranus")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * URANUS << " lbs." << endl;
    
    else if (planet == "Neptune")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * NEPTUNE << " lbs." << endl;
    
    else if (planet == "Pluto")
        cout << "Your weight: " << weight << " lbs on " << planet << " is: " 
        << weight * PLUTO << " lbs." << endl;
    else
    {
        cout << "Incorrect, the celestial body name must be typed as: " 
        "Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune "
        "Pluto, or Moon. " << endl;
    }
    
}

int main()
{
    int choice;
    do
    {
    cout << 
            "\n"
            "______________________________________\n"  
            " |This program calculates the weight |\n" 
            " |of a person in one of the celestial|\n" 
            " |bodies: Mercury, Venus, Earth, Mars|\n" 
            " |Jupiter, Saturn, Uranus, Neptune,  |\n" 
            " |Pluto, and Moon.                   |\n" 
            " |-----------------------------------|\n" 
            " |                  MENU             |\n"
            " |      0: Quit Program              |\n"
            " |      1: Calculate the weight      |\n"
            " |-----------------------------------|\n"
            " |      Enter your choice: ";
    cin >> choice;
    
    switch(choice)
    {
    case 0: cout << "Exiting Program" << endl;
         break;
    case 1: userInput();
            calculatingWeight();
         break;
    default: cout << "Invalid choice, try again!" << endl;
    }
    
}
    while( choice != 0 );
    
    return 0;
}


I don't know why the menu isn't copying right but I promise it's straight and even on my end.
I am curious as to how to do the program with the
double planetWeight;

Edit; the menu copied fine it just looks weird on the text.
Last edited on Mar 15, 2021 at 6:00pm
Mar 15, 2021 at 6:41pm
Hello av16352,


I am curious as to how to do the program with the double planetWeight;


In the first bit of code I found the same problem and changed the else part to:
1
2
3
4
5
6
7
8
9
10
else
{
    cout << 
        "\n"
        "     Incorrect, the celestial body name must be typed as:\n"
        "     Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune\n"
        "     Pluto, or Moon. " << endl;

    return;
}

Since the function is "void" for the return value just use "return". Then the function will work fine.


I don't know why the menu isn't copying right but I promise it's straight and even on my end.


This may be a problem in how the "tab" key is set. It may be fine on your end, but be interpreted differently here.

This is something you will have to check. Most likely there if a tools manu item and under that it may say "options" or "preferences". Look for a section called "Text Editor" from there the section for "tabs" may be under a section called "C/C++". Whatever numerical value shows up set them to 4 and choose "spaces" over the "tab". This should help when posting code here.


I went ahead and added the new line sequence character \n for the menu part. We haven't learned that but it was simple enough for me to explain it in notes so he won't deduct points for something he hasn't taught us yet.


Just because it has not been taught in class does not mean that you can learn from somewhere else.

In my first programming class, Assembly language for an IBM mainframe, I had a very poor teacher that quarter, but he did say 1 thing that was very useful.

"Read ahead in the text book. If you wait for me to lecture on something you will not be able to finish your assignments in time." Now the text book was about 30 8 1/2 x 11 sheets and they may have only been printed on 1 side, So reading the book was easy.

I believe it is always good to learn where ever you can and only if the teacher is very strict do you give them what they want based on what they have taught.

"const" and "constexpr" are in 1 sense the same. Just think of "constexpr" as being an upgrade. As you progress "constexpr" will be used more in the 2017 and 2020 standards more. Something you should be getting use to for the future.

Have a look at: https://en.cppreference.com/w/cpp/language/constexpr

Andy
Mar 15, 2021 at 7:07pm
Andy,

Thank you for that return; part, it fixed it. Oh ok that's good to know for future use.

I have learned a lot more these past 2 days while doing this assignment and now I will go on my own and learn about arrays and so forth before class on Wednesday because this teacher isn't really good at explaining the material.

Thank you for the link, I'll read it when I finish my math hw :p

Thank you for your feedback and being patient, it really has helped a lot and refreshed my memory!

Edit, I prefer the planetWeight so this is my final product for class. I will work on this and re-arrange it without global variables and the re-numeric input for cin. Will also get rid of most of the endl; statements.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

double weight;
string planet;

const double MERCURY = 0.4155;
const double VENUS = 0.8975;
const double EARTH = 1.0000;
const double MOON = 0.1660;
const double MARS = 0.3507;
const double JUPITER = 2.5374;
const double SATURN = 1.0677;
const double URANUS = 0.8947;
const double NEPTUNE = 1.1794;
const double PLUTO = 0.0899;

void userInput()
{
    
    cout << "Please enter your weight in pounds: " << endl;
    cin >> weight;
    
    cout << "Enter the name of a celestial body: " << endl;
    cin >> planet;
}    
void calculatingWeight()
{
    double planetWeight;
    
    cout << fixed << showpoint << setprecision(2);

    if (planet == "Mercury")
        planetWeight = weight * MERCURY;
    
    else if (planet == "Venus")
        planetWeight = weight * VENUS;
        
    else if (planet == "Earth")
        planetWeight = weight * EARTH;
    
    else if (planet == "Moon")
        planetWeight = weight * MOON;
    
    else if (planet == "Mars")
        planetWeight = weight * MARS;
    
    else if (planet == "Jupiter")
        planetWeight = weight * JUPITER;
    
    else if (planet == "Saturn")
        planetWeight = weight * SATURN;
    
    else if (planet == "Uranus")
        planetWeight = weight * URANUS;
    
    else if (planet == "Neptune")
        planetWeight = weight * NEPTUNE;
    
    else if (planet == "Pluto")
        planetWeight = weight * PLUTO;
    else
    {
        cout << "Incorrect, the celestial body name must be typed as: " 
        "Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune "
        "Pluto, or Moon. " << endl;
        
        return;
    }
        cout << "Your weight of: " << weight << " lbs on " << planet << " is: " 
        << planetWeight << " lbs." << endl;
}

int main()
{
    int choice;
    do
    {
    cout << 
            "\n"
            "______________________________________\n"  
            " |This program calculates the weight |\n" 
            " |of a person in one of the celestial|\n" 
            " |bodies: Mercury, Venus, Earth, Mars|\n" 
            " |Jupiter, Saturn, Uranus, Neptune,  |\n" 
            " |Pluto, and Moon.                   |\n" 
            " |-----------------------------------|\n" 
            " |                  MENU             |\n"
            " |      0: Quit Program              |\n"
            " |      1: Calculate the weight      |\n"
            " |-----------------------------------|\n"
            " |      Enter your choice: ";
    cin >> choice;
    
    switch(choice)
    {
    case 0: cout << "Exiting Program" << endl;
         break;
    case 1: userInput();
            calculatingWeight();
         break;
    default: cout << "Invalid choice, try again!" << endl;
    }
    
}
    while( choice != 0 );
    
    return 0;
}


Last edited on Mar 15, 2021 at 7:12pm
Mar 15, 2021 at 7:11pm
Any time. Glad it helped.

Andy
Topic archived. No new replies allowed.