4
votes

Créer une variable de chaîne et demander une entrée sur la même ligne?

Je déteste absolument ces étapes inutiles de la programmation où vous déclarez et attribuez une variable sur une ligne et demandez une entrée dans la suivante.

Pour faire court, je veux créer une variable et demander l'entrée tout sur la même ligne.

Actuellement, j'écris du code comme celui-ci:

string name = cin >> name

C'est un peu mon objectif:

string name = "";
cout << "Please enter your name: ";
cin >> name; //Too many steps for no reason


4 commentaires

nom de chaîne; cin >> nom; Un caractère plus court que votre syntaxe hypothétique.


Ecrivez une fonction getInput qui encapsule le texte de la chaîne ; std :: cin >> texte; return text; pour que vous puissiez écrire std :: string name = getInput (); .


Une seule ligne, contenue dans une seule instruction: auto name = [] () {std :: string name; cin >> nom; return name;} (); Bien que, techniquement, il y ait plusieurs instructions dans l'instruction.


@IgorTandetnik Je sais que ce genre d'astuce existe mais ce n'est pas le but. Voir la façon dont je l'ai écrit, la syntaxe est importante


3 Réponses :


6
votes

Vous pouvez essayer d'écrire une fonction de modèle, par exemple

template <typename T>
std::optional<T> read (std::istream & in = std::cin)
{
    T x; in >> x; return in ? x : std::nullopt;
}

template <typename T>
T read_loop (std::istream & in = std::cin)
{
    while (true)
    {
        auto input = read<T>(in);
        if (input) return *input;
        in.clear();
        std::cout << "try again: ";
    }
}

et l'utiliser comme

 auto x = read<int>();

Si vous souhaitez valider l'entrée utilisateur ( et vous le voulez certainement do dans le code réel), vous pouvez utiliser par exemple std:: optionnel:

template <typename T>
T read (std::istream & in = std::cin)
{
    T x; in >> x; return x;
}


7 commentaires

Je ne comprends pas non plus le vote défavorable. Je veux dire, si la question est "Comment transformer cette tâche en quelque chose que je peux demander en une seule ligne", il semble que l'écriture d'une fonction devrait être l'une des premières choses qui me viennent à l'esprit. Edit: surtout si ce que vous attendez de cette tâche est d'obtenir une valeur.


Cette réponse pourrait être améliorée en vérifiant si l'entrée a réussi.


@ FrançoisAndrieux Bonne idée, je vais mettre à jour la réponse.


Jamais travaillé avec des modèles auparavant et cela semble encore plus de travail que de simplement les écrire sur plusieurs lignes;)


@StellarEquilibrium ça s'appelle une abstraction. Il résume le travail acharné que vous devrez écrire dans des composants réutilisables.


clear () ne suffit pas. Il efface les indicateurs d'erreur du flux, mais les mêmes données attendent d'être lues à nouveau (éventuellement interprétées de manière différente), vous avez donc une boucle infinitive.


@StellarEquilibrium Vous n'écrivez le modèle qu'une seule fois. En fait, vous pouvez simplement couper et coller le code ci-dessus, puis l'utiliser toute une vie.



3
votes

Alors, quel est le problème? Si vous avez du code répétitif (pas forcément ennuyeux), insérez-le simplement dans la fonction / méthode:

template<typename T>
auto consoleInput(std::string_view request) -> T
{
    std::cin.sync();
    std::cout << request;
    T x;
    while(! (std::cin >> x)) {
        std::cin.clear();
        std::cin.ignore(200, '\n');
        std::cout << "\ntry again: " << request;
    }
    return x;
}

auto name = consoleInput<std::string>("Provide a name");

https://wandbox.org/permlink/iUWmrMCbCWGjoiGu


1 commentaires

Vous étiez un peu plus rapide que moi. +1 pour validation



2
votes

oui je l'utilise avec fierté :)

Vous ne devriez vraiment pas. Apprenez à écrire de bonnes petites fonctions faciles à lire avec le flux de contrôle le plus simple. En outre, .

Vous pouvez le faire en déplaçant les étapes pour initialiser la variable dans une fonction:

int main() {
    auto name = ask_user<std::string>("What's your name? ");
}

Vous pouvez maintenant faire vos entrées comme ça:

XXX

2 commentaires

Vous n'êtes pas obligé de maintenir votre code, si personne ne peut le lire :) (sauf quand son stackoverflow, alors je l'évite à tout prix.) Je n'ai jamais travaillé avec des modèles auparavant et cela semble encore plus de travail que juste les écrire sur plusieurs lignes;)


Le codage @StellarEquilibrium est une activité sociale. Vous devrez coder avec de nombreuses personnes. Faites-le de la bonne façon maintenant ou une grosse surprise vous attendra.