11
votes

Invite en toute sécurité pour oui / non avec CIN

Je suis dans une classe d'introduction à C ++ et je me demandais une meilleure méthode de vérification si l'entrée était le type souhaité.

Est-ce un bon moyen de faire cela? Je viens d'un contexte PHP / Perl qui me rend plutôt inquiète d'utiliser tandis que des boucles. xxx

est-ce un coffre-fort façon de faire ceci ou suis Je m'ouvre dans un monde de blessures, que je soupçonne? Quelle serait une meilleure façon de vous assurer que je veux obtenir l'entrée que je veux avant de continuer?


9 commentaires

Quelle est la signification du numéro 10 dans cette situation?


Il n'y a pas de sens réelle, je l'envisageons comme indiquant qu'il y avait une limite à la durée de la longueur de la boucle. Mais même il y a un risque de quoi si je n'absions jamais.


Je suppose que le titre devrait vraiment être alors que (condition) vs tandis que (vrai) {si (condition) se casser.


Titre modifié; Merci pour l'entrée!


"Je viens d'un contexte PHP / Perl qui me fait plutôt inquiète d'utiliser tandis que des boucles" - PHP et Perl ont pendant boucles ...


Je sais qu'ils ont des boucles, beaucoup de mes professeurs nous apprendraient de ne pas les utiliser car ils craignaient que nous écrasions des serveurs. Certainement pas le meilleur moyen d'apprendre à programmer cependant.


@Blueraja: boucles basées sur la plage avec foreach et similaire remplacée de nombreuses utilisations de pour et pendant dans les langues dynamiques. Cela a eu le bon effet d'écraser de nombreux insectes dans la logique de terminaison et de l'effet laide que les gens se sentent déséquilibrés lorsqu'ils ont besoin d'un pendant . Mais ce n'est qu'une fois depuis un moment, à coup sûr!


@Just: Il n'y a pas vraiment de de remplacement pour pendant (type! = 'n' && type! = 'y')


@Blueraja j'ai écrit " foreach [...] remplacé de nombreuses utilisations de pour et pendant ", remarquez beaucoup par opposition à tout . Mon affirmation selon laquelle "Poeple se sent maintenant insécurité quand ils ont besoin d'un tandis que [instruction]" "devrait également préciser que tandis que est toujours nécessaire. Mais peut-être que je ne me confond que des langages dynamiques avec des applications "Enterprise" (Web) où la grande majorité des boucles sont sur des collections telles que la DB Results. Par exemple, une application bancaire utilisée contient 80 pendant LOOPS et 1590 foreach boucles.


15 Réponses :


1
votes

C'est bien. Si vous voulez qu'il tient de temps après plusieurs échecs, vous pouvez utiliser le i <10 mais cela ne vaut pas la peine.


0 commentaires

4
votes

Utilisation peut utiliser

do {
    program;
} while (condition_to_repeat);


0 commentaires

26
votes

Personnellement, j'irais avec: xxx


13 commentaires

Ce n'est pas bon. Si CIN est fermé, il sera bouclé pour toujours "Avez-vous été admis? [Y / n]" à COUT . Il est important de toujours tester le succès de l'opération de saisie avant de tester ce qu'il est censé avoir lu.


Beaucoup plus lisible et concis que mon code! Les whiles sont-ils couramment utilisés pour vous assurer que la saisie est correcte et que sinon demander à nouveau?


Les baies sont principalement utilisées dans les cas que vous souhaitez prendre certaines mesures avant de vérifier la condition et cette action serait répétée si votre condition est vraie. En cas d'entrée de l'utilisateur, avant de vérifier la condition que vous souhaitez obtenir une entrée, les whiles sont donc pratiques.


Les whiles sont généralement utilisés chaque fois que vous souhaitez que le code soit exécuté au moins une fois.


Edité par le commentaire de Charles Bailey - il est vraiment correct. Et le commentaire d'Alex répond aux commentaires de Levi. Vous pouvez utiliser une boucle normale pendant ce cas si vous initialisez le type à autre chose que Y ou N.


Est-ce mieux? Si CIN échoue, il boucle toujours pour toujours.


@Mcaden La condition devrait être (! Cin.fail () && Type! = 'Y' && Type! = 'N');


@ Charles - Vous avez oublié certaines des subtilités d'utiliser CIN, merci. @ALEX - Comment est-ce différent?


@Mcaden Si la CIN échoue, vous ne voulez pas boucler pour toujours. Dans votre implémentation, si la CIN échoue, la condition est toujours vraie car le type n'est ni 'y' ni 'n', de sorte que la boucle continue. Au lieu de cela, vous voulez vous assurer que si les CIN échouent, la condition devient FALSE, Ainsi (! Cin.fail () && Type! = 'Y' && Type! = 'N')


Si CIN a vraiment été fermé puis appelant clair () peut être futile. La prochaine tentative de lecture réaffecterait immédiatement le bit d'échec et la rédaction de la boucle infinie sur cout reste.


Mal interprété et ne pensait pas réellement à un ruisseau fermé. J'ai raté cela dans les commentaires de Charles. Charles et Alex sont les deux corrects.


Bien sûr, les effectifs / ignorent, en fonction de la dernière entrée effectuée (avant cette boucle). Vous devriez toujours lire une ligne complète lorsque vous effectuez une entrée (si elle fait une entrée basée sur la ligne) plutôt que de laisser une nouvelle ligne ou non. ! cin.fail () est identique à celui CIN .


24 UPVOTES, 500 personnes discutant d'un problème qui vient juste après «Bonjour World», et le résultat final est quelque chose qui pendra immédiatement sur l'ignore et ne commencera même pas à travailler. Je ne sais pas ce qui est plus pathétique, C ++ iostreams ou que les gens se disputeront au cours des meilleurs détails, mais ne vous embêtez jamais de courir la fichue chose.



2
votes

Pourquoi ne pas le faire de cette façon? XXX


4 commentaires

J'ai considéré la cible ... Ceci est une classe d'introduction à C ++. Il est supposé dans ces premières classes que CIN est connectée à la ligne de commande / OS et qu'elle n'échoue pas.


^ Z sous Windows ou ^ D dans UNIX provoquera la ligne de commande de la ligne de commande la première fois et échoue à la deuxième fois.


@JMUCCHIELLO: Cela fixera la première fois qu'il atteint EOF d'essayer de lire le caractère. (Le caractère ne peut pas être lu, qui doit être lu, de sorte que le flux a «échoué».)


D'accord. Peu importe, il ne sortira toujours jamais.



0
votes

Je n'ai jamais codé dans Perl / PHP avant mais basé sur votre question et l'exemple ici est une solution simple.

    char c;
while(true){
    cout << "Were you admitted? [y/n]" << endl;
    cin >> c;
    if(c == 'y')
        break;
}
cin.get(c);
return 0;


2 commentaires

Qu'est-ce que cela résolve ?? Avez-vous décidé de supposer que l'exemple Snippet est l'ensemble du principal () ?


Donc, vous venez de prendre le code de Levi's Code Snippet (qui était la question) supprimé l'égalité à la condition de «N» (?!?! ??!?!?!) Et postez-le comme une solution?!?!?!?!?!?!



9
votes

Personnellement, je ferais une fonction distincte, cela permet de mettre la sortie rapide et de la lecture d'une réponse une expression logique à placer dans une boucle de travail.

Test si la lecture a été réussie est essentielle au bon fonctionnement. du code.

Je préférerais également utiliser std :: getline pour obtenir une ligne à la fois car cela aide à réduire les erreurs causées par la lecture du reste de la moitié ligne qui résultait d'une lecture partielle aux réponses des utilisateurs antérieures. xxx


2 commentaires

+1. Utilisez A pour la boucle pour étendre la variable. Le retour du flux est plus polyvalent et permet toujours de tester comme si c'était un bool.


Quelle variable doit être scopée? Le type ?



1
votes

Et n'oubliez pas de faciliter la vie de votre utilisateur potentiel en expliquant chaque étape et même fournir l'entrée insensible à la casse. xxx


0 commentaires

0
votes

Le faire ... pendant que la construction est en quelque sorte faite pour cela, mais vous pouvez également faire tout le travail dans la condition de boucle: xxx

:)

Et si vous ne voulez pas tester le succès de std :: Cin >> Réponse (par exemple, vous voulez une boucle infiniment avec Ctrl + Z), vous pouvez remplacer && pour virgule :)

Pas entièrement sérieux, même si les méthodes qui mettent la prompte dans la condition peuvent parfois améliorer la logique de telles boucles (éviter pause ).


0 commentaires

0
votes

Je vois deux "problèmes" ici. Le premier est l'utilisation de temps (vrai). Je ne pense pas que ce soit une bonne pratique (bien que cela soit probablement une question de goût pour de nombreuses personnes). La rupture à l'intérieur d'une boucle est cependant intéressante pour la recherche:

int main()
{
    int ch;
    std::string type;

    do {
        getline( std::cin, type );

        if ( cin.fail() ) {
            ch = EOF;
            break;
        }

        ch = tolower( type[ 0 ] );
    } while( ch != 'y' && ch != 'n' );

    // interesting things here...

    return 0;
}


0 commentaires

1
votes

L'entrée basée sur la ligne ne doit pas nécessairement être verbose, vous pouvez le faire succinct , avec une seule fonction que vous écrivez une fois, qui gère toujours les cas d'angle: xxx


0 commentaires

0
votes

Modification de ce que @mcaden a dit, essayez ceci corrige le bogue où si vous entrez plusieurs caractères, le test ne vérifie que la première lettre.

    char type;
    char buffer[128];
    do
    {
      cout << "Were you admitted? [y/n]" << endl;
      cin >> buffer;
      type = buffer[0];
      cout << type << "\n";
    }while( !cin.fail() && type!='y' && type!='n' );


0 commentaires

0
votes

Voici une autre façon de demander à Y / N. "Alors que" vous n'obtenez pas ce que vous voulez, "commutateur" sur votre entrée. Faire tout ce que vous aimez avec elle; Cela fonctionne simplement.

#include "stdafx.h"
#include <iostream>

int main()
{
    bool play = true; // Initialize play to true.
    char choice;
    while (play) // While play is true, do the following:
    {
        std::cout << "Play again? [y/n] -> ";
        std::cin >> choice;
        switch (choice)
        {
        case 'n':           // We can fall through here because we
            play = false;   // don't do anything with 'y' anyway.
        case 'y':           // Remember; play is already true unless
            break;          // we changed it to false with 'n'.
        default:  // We'll simply assume anything else is a fail!
            std::cin.clear();
            std::cin.ignore(1024, '\n');
            break;
        }
        // Break out here and check the "while" condition again...
    }
    // When play becomes false, we exit the while statement.
}


0 commentaires

0
votes

Un autre moyen de demander à Y / N. "Faites" cela "alors que" vous n'obtenez pas ce que vous voulez. Faire tout ce que vous aimez avec elle; Cela fonctionne simplement.

#include "stdafx.h"
#include <iostream>

int main()
{
    bool accepted;
    char answer;
    do
    { // Ask for 'y' or 'n' at least once
        std::cout << "Accepted? [y/n] -> ";
        std::cin >> answer;
        if (std::cin.fail())
        {                                // not a valid character?
            std::cin.clear();
            std::cin.ignore(1024, '\n');
        }
        if (answer == 'n')
        {                                // character is 'n'?
            accepted = false;
        }
        else
        {                                // character is 'y'?
            accepted = true;
        }
         //    not valid    |or|    not 'n'     |or|    not 'y'
    } while (std::cin.fail() || !(answer == 'n') || !(answer == 'y'));  
}


0 commentaires

1
votes

Voici un chemin plus court

char type;
while (type != 'y') 
{
    cout << "Were you admitted? [y/n]" << endl;
    cin >> type;   
}


0 commentaires

0
votes
char yn;
bool choice;
do
    {
           
        cout<<"Would you like try again?\n";
        cout<<"Y for yes N for no: ";
        cin>>yn;
    
        while (yn != 'n'&& yn != 'N'&&yn != 'y'&&yn != 'Y')
        {
            cout<<"Y or N please: ";
            cin>>yn;
        }
        
        if (yn == 'n'||yn == 'N')
            choice = false;
        if(yn == 'y'||yn == 'Y')
            choice = true;
        
    } while (choice == true);

0 commentaires