Michael Hall
Michael Hall

Reputation: 31

C++ Cin not executing properly

I am having problems getting "cin >> calories" to execute properly. The code automatically sets calories = to -279846518796 and sometimes other numbers ( usually a big negative number like before). Thus making the end results a mess. Even if I set "calories" as an int I get the same error.

#include <iostream>

int main( ) 
{
int height, weight, age, edible_newfoods;
double bmr, calories;
char gender, activity_level, newfood;

//Take user inputs.
cout << "Please provide your information." << endl;
cout << "male or female (m or f): ";
cin >> gender;
cout << "age in years: ";
cin >> age;
cout << "weight in pounds: ";
cin >> weight;
cout << "height in inches: ";
cin >> height;

//Ask the user how active they are, to get an input between four choices
cout << endl << "How active are you?" << endl; 
cout << "   s - sedentary" << endl;
cout << "   c - casual exerciser--exercise ocasionally" << endl;
cout << "   a - active exerciser--exercise 3-4 days a week" << endl;
cout << "   d - devoted exerciser--exercise everyday" << endl;

//Take users activity level as a char
cout << "Enter the level of association with your activity level: ";
cin >> activity_level;

//Adding more food
cout << endl << "What type of food do you want to eat?" << endl;

cout << "Please use _ between words to create a single word. ";
cin >> newfood;

cout << "How many calories per item? ";
//This is where the cin automatically makes calories a giant negative number.
// causing the final output of results to be a mess.
cin >> calories;

//Calculations - Adjusting BMR to accommodate for activity level
switch (activity_level)
{
    case 's':
    case 'S': activity_level = 0.95; break;
    case 'c':
    case 'C': activity_level = 1.30; break;
    case 'a': 
    case 'A': activity_level = 1.40; break;
    case 'd':
    case 'D': activity_level = 1.50; break;
} 

if (age <= 65 && (gender == 'm' || gender == 'M')) {
    bmr = 1.375 * ((66 + 6.3 * weight) + (12.9 * height) - (6.8 * age));
}
else {
    bmr = 1.375 * ((655 + 4.3 * weight) + (4.7 * height) - (4.7 * age));
}

bmr = bmr * activity_level;

edible_newfoods = bmr / calories;

cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(0);

//output the results to user.
cout << endl << "The BMR for a " << weight << " pound " << gender << " who is " << age << " years    old is " << bmr
<< " calories number of " << newfood << " eaten = " << edible_newfoods;
}

Please be kind, I am new to stackoverflow, and coding. Any help would be appreciated. Thanks

Upvotes: 0

Views: 168

Answers (2)

M.M
M.M

Reputation: 141648

The problems start here:

cout << "Enter the level of association with your activity level: ";
cin >> activity_level;

activity_level has type char. When you do cin >> a char, then leading whitespace is not skipped. So this line picks up the Enter key that you pressed after the previous numeric input. You should have noticed that the program never waited for you to enter anything here, and went straight on to displaying "Enter the level of association with your activity level".

The next problem is with the next input:

cout << "Please use _ between words to create a single word. ";
cin >> newfood;

newfood has type char. That means a single character. It can't hold any words (except "a" or "I").

To fix both of these problems , use std::string instead of char, for all three of those chars. Further, instead of using cin >> newfood which only gets a single word,getline(cin, newfood); which gets the whole line (and consumes the newline). Use this technique for activity_level and gender too.

The next problem is at:

switch (activity_level)
{
    case 's':
    case 'S': activity_level = 0.95;

You are trying to store 0.95 in a char which won't work. Use a new variable here, e.g. double activity_factor. Make sure to have a default value set, or a default case. Otherwise you will get garbage if the person didn't enter an expected character.

Finally , to prevent garbage output when there was invalid input, you can add the following before your final output:

if ( !cin )
{
    cerr << "Invalid input entered.\n";
    return 0;
}

or something similar. Then at least you get something sensible. To give more targeted error messages, perform this check after every input.

Upvotes: 0

AlexD
AlexD

Reputation: 32616

activity_level is of type char, assigning double to it does not look correct:

char gender, activity_level, newfood;
...
activity_level = 0.95;

While it is still a valid language construction, it results in truncating of floating part and assigning 0 to activity_level. See comment of @KeithThompson.

It seems that two different variables are required,

  • one (char) to be keep the input and be used in the switch, and
  • another one (double) as the factor for bmr = bmr * activity_level;

Upvotes: 1

Related Questions