4

My loop works good until i enter the last value being the input for gender, when "true" is inputted, the loop ignores cin's for the remaining loops and just prints the text in cout until loop is over, any ideas how to make the loop ask for input on every loop or where did i make a mistake? ps: it's a schoolwork, so i can't change the struct which is given. Thanks for any suggestions. code snippet:

int main()
{
    struct Patient
    {
        double height;
        double weight;
        int age;
        bool isMale;
    };
    Patient ListOfPatients[4];
    int iii = 0;

    while (iii < 4)
    {
        cout << "enter the height (eg. 1.80 metres) of patient number  " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].height;
        cout << "enter the weight (eg. 80kg) of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].weight;
        cout << "enter the age of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].age;
        cout << "is the patient a male? (true = male or false = female) " << endl;
        cin >> ListOfPatients[iii].isMale;

        iii++;
    }

    return 0;
}
1

4 Answers 4

4

The problem is when you read isMale. A bool is really a number, 0 for false, 1 for true. You can't read a string into it.

What happens is that you end up with a bunch of characters in the stream that can't be read by any of the >> operations, so they all just fail in a row. Try passing in 1 or 0 on the command line, and it all works fine.

If you want the user to be able to pass in a string and then treat this as a bool, you can use a utility provided exactly for this, or do it manually just to help you understand.

To use the standard utility, it is called std::boolalpha and comes in the <iomanip> header:

std::cin >> std::boolalpha >> ListOfPatients[i].isMale;

To do it manually, read this into a std::string object and do some comparison yourself, like this:

std::string tmpIsMale;
std::cin >> tmpIsMale;
ListOfPatients[i].isMale = (tmpIsMale == "true");

It is also a good idea to check the state of the stream after you try to read from it, for precisely this reason. You can put the stream directly into an if for this:

std::cin >> someVariable;
if (!cin) { // cin is not in a good state
    std::cerr << "Failed to read someVariable, please try again with a proper value!\n";
    return 1;
}

A few asides and bad practices you may want to avoid:

  1. using namespace std; is widely considered to be bad practice.
  2. std::endl is a bit more contentious, but the way you are using it suggests you don't understand it.
  3. Gender isn't a boolean option. I know it's not a strictly technical matter, and if the struct is provided by your teacher you are a bit stuck, but come on, it's 2019! Learning to write good programs doesn't just mean the technicalities of the language, but learning how to write programs that are good for the users too, so it's a good idea to get into good habits early.
Sign up to request clarification or add additional context in comments.

3 Comments

There's std::boolalpha just for this.
Thanks @SombreroChicken - I couldn't remember if this works for cin as well as cout, and hadn't checked yet.
To address your third aside point... first of all this is a very simple application measuring only 4 characteristics of a medical patient, so I don't see why OP should be including a wide spectrum genders. Secondly, the measure isn't of gender, it's a medical application and so likely a measure of sex, which for the most part is binary. You're right, its not a technical matter and with all due respect I think you should leave it out of your next answer.
2

You can use the stream manipulator boolalpha to not do any of the comparing yourself:

cin >> std::boolalpha >> cListOfPatients[iii].isMale >> std::noboolalpha;

Comments

2

You can't assign string true into boolean field. Please check corrected example.

int main()
{
    struct Patient
    {
        double height;
        double weight;
        int age;
        bool isMale;
    };
    Patient ListOfPatients[4];
    int iii = 0;

    while (iii < 4)
    {
        string sIsMale = "";

        cout << "enter the height (eg. 1.80 metres) of patient number  " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].height;
        cout << "enter the weight (eg. 80kg) of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].weight;
        cout << "enter the age of patient number " << iii + 1 << " :" << endl;
        cin >> ListOfPatients[iii].age;
        cout << "is the patient a male? (true = male or false = female) " << endl;
        cin >> sIsMale;
        ListOfPatients[iii].isMale = sIsMale == "true";

        iii++;
    }

    return 0;
}

Comments

1

The problem here is that isMale is a boolean and a String "true" is not the same as a boolean! The reason why it does not crash but simply runs through the rest of the program is because your cin is still reading old characters from the input stream. A simple solution to this would be to convert true or false to booleans and then use these to set isMale. This can be accomplished with:

String toBeConverted;
cin >> toBeConverted;
ListOfPatients[iii].isMale = toBeConverted == "true";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.