4
votes

tandis que la boucle ne demande pas d'entrée utilisateur (c ++)

Ma boucle fonctionne bien jusqu'à ce que j'entre la dernière valeur étant l'entrée pour le genre, lorsque "true" est entré, la boucle ignore les cin pour les boucles restantes et imprime simplement le texte en cout jusqu'à ce que la boucle soit terminée, toutes les idées comment faire faire la boucle demander une entrée sur chaque boucle ou où ai-je fait une erreur? ps: c'est un travail scolaire, donc je ne peux pas changer la structure qui est donnée. Merci pour vos suggestions. extrait de code:

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 commentaires

en.cppreference.com/w/cpp/io/manip/boolalpha Cela vous permettra de saisir "vrai / faux".


4 Réponses :


4
votes

Le problème est lorsque vous lisez isMale . Un booléen est vraiment un nombre, 0 pour false , 1 pour true . Vous ne pouvez pas y lire une chaîne.

Ce qui se passe, c'est que vous vous retrouvez avec un tas de caractères dans le flux qui ne peuvent être lus par aucune des opérations >> , donc ils échouent tous dans une rangée. Essayez de passer 1 ou 0 sur la ligne de commande, et tout fonctionne bien.

Si vous voulez que l'utilisateur puisse transmettre un string, puis le traiter comme un bool , vous pouvez utiliser un utilitaire fourni exactement pour cela, ou le faire manuellement juste pour vous aider à comprendre.

Pour utiliser l'utilitaire standard, il s'appelle std :: boolalpha et vient dans l'en-tête :

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

Pour le faire manuellement, lisez ceci dans un objet std :: string et faites une comparaison vous-même, comme ceci:

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

C'est aussi une bonne idée de vérifier l'état de le flux après avoir essayé de le lire, précisément pour cette raison. Vous pouvez placer le flux directement dans un si pour cela:

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

Quelques inconvénients et mauvaises pratiques que vous voudrez peut-être éviter:

  1. using namespace std; est largement considéré comme une mauvaise pratique.
  2. std :: endl est un peu plus controversé, mais la façon dont vous l'utilisez donne à penser que vous ne le comprenez pas.
  3. Le sexe n'est pas une option booléenne. Je sais que ce n'est pas une question strictement technique, et si la structure est fournie par votre professeur, vous êtes un peu coincé, mais allez, c'est 2019! Apprendre à écrire de bons programmes ne signifie pas seulement les aspects techniques du langage, mais aussi apprendre à écrire des programmes qui sont bons pour les utilisateurs, c'est donc une bonne idée de prendre de bonnes habitudes tôt.


3 commentaires

Il y a std :: boolalpha juste pour ça.


Merci @SombreroChicken - Je ne me souvenais pas si cela fonctionne pour cin ainsi que pour cout , et je n'avais pas encore vérifié.


Pour répondre à votre troisième point de côté ... tout d'abord, il s'agit d'une application très simple ne mesurant que 4 caractéristiques d'un patient médical, donc je ne vois pas pourquoi OP devrait inclure un large spectre de genres. Deuxièmement, la mesure n'est pas le sexe, c'est une application médicale et donc probablement une mesure du sexe, qui est pour la plupart binaire. Vous avez raison, ce n'est pas une question technique et avec tout le respect que je vous dois, je pense que vous devriez le laisser de côté dans votre prochaine réponse.



2
votes

Vous ne pouvez pas affecter la chaîne true dans un champ booléen. Veuillez vérifier l'exemple corrigé.

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


0 commentaires

1
votes

Le problème ici est que isMale est un booléen et une chaîne "true" n'est pas la même chose qu'un booléen ! La raison pour laquelle il ne plante pas mais parcourt simplement le reste du programme est que votre cin lit toujours les anciens caractères du flux d'entrée. Une solution simple à cela serait de convertir true ou false en booléens, puis de les utiliser pour définir isMale . Ceci peut être accompli avec:

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


0 commentaires

2
votes

Vous pouvez utiliser le manipulateur de flux boolalpha pour ne faire aucune comparaison vous-même:

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


0 commentaires