цикл while не запрашивает пользовательский ввод (c ++) - PullRequest
4 голосов
/ 12 марта 2019

Мой цикл работает хорошо, пока я не введу последнее значение, являющееся вводом для пола, когда введено «true», цикл игнорирует cin для оставшихся циклов и просто печатает текст в cout, пока цикл не закончится, любые идеи, как это сделать сделать цикл запрашивать ввод для каждого цикла или где я сделал ошибку? PS: это школьная работа, поэтому я не могу изменить структуру, которая дается. Спасибо за любые предложения. фрагмент кода:

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

Ответы [ 4 ]

4 голосов
/ 12 марта 2019

Проблема в том, что вы читаете isMale.bool - это действительно число, 0 для false, 1 для true.Вы не можете прочитать строку в нее.

В результате получается, что в потоке вы получаете кучу символов, которые не могут быть прочитаны ни одной из операций >>, поэтому все они простопотерпеть неудачу подряд.Попробуйте ввести 1 или 0 в командной строке, и все будет работать нормально.

Если вы хотите, чтобы пользователь мог передавать строку, а затем трактовать это как bool,вы можете использовать утилиту, предоставленную именно для этого, или сделать это вручную, чтобы помочь вам понять.

Чтобы использовать стандартную утилиту, она называется std::boolalpha и входит в заголовок <iomanip>:

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

Чтобы сделать это вручную, прочитайте это в std::string объект и сделайте некоторое сравнение самостоятельно, например так:

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

Также неплохо проверить состояние потокапосле того, как вы пытаетесь читать с него, именно по этой причине.Вы можете поместить поток непосредственно в if для этого:

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

Несколько побочных эффектов и плохих практик, которые вы можете избежать:

  1. using namespace std; считается плохой практикой.
  2. std::endl немного спорнее, но то, как вы его используете, говорит о том, что вы этого не понимаете.
  3. Пол не является логическим параметром.Я знаю, что это не сугубо технический вопрос, и если структура предоставлена ​​вашим учителем, вы немного застряли, но это же 2019 год!Умение писать хорошие программы означает не только технические особенности языка, но и умение писать программы, которые также полезны для пользователей, поэтому неплохо бы рано освоить хорошие привычки.
2 голосов
/ 12 марта 2019

Вы можете использовать потоковый манипулятор boolalpha, чтобы не выполнять сравнение самостоятельно:

cin >> std::boolalpha >> cListOfPatients[iii].isMale >> std::noboolalpha;
2 голосов
/ 12 марта 2019

Вы не можете присвоить строку true в логическое поле. Пожалуйста, проверьте исправленный пример.

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;
}
1 голос
/ 12 марта 2019

Проблема в том, что isMale - это boolean, а строка "true" - это не то же самое, что boolean! Причина, по которой он не падает, а просто проходит через остальную часть программы, заключается в том, что ваш cin все еще читает старые символы из входного потока. Простым решением этой проблемы будет преобразование истинного или ложного в логическое значение, а затем использование их для установки isMale. Это может быть достигнуто с помощью:

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