web-dev-qa-db-fra.com

Pause de la console dans le programme C++

Quel est le meilleur moyen de mettre la console en pause dans les programmes C++?

  1. en utilisant cin.get()
  2. ou en utilisant system("pause")
  3. ou en utilisant des fonctions C comme getch() ou getchar()?

Est-il vrai que l'utilisation de system("pause") conduit à un code non portable et ne peut pas fonctionner sous UNIX?

Est-il préférable d'utiliser cin.get () pour mettre la console en pause? 

44
Destructor

Il peut y avoir un meilleur moyen (comme utiliser la cin.get() portable), mais un bon moyen n'existe pas. Un programme qui a fait son travail devrait s’arrêter et redonner ses ressources à l’ordinateur.

Et oui, toute utilisation de system() conduit à un code non transférable, car le paramètre est transmis au shell propriétaire de votre processus.

Avoir le code de pause dans votre code source tôt ou tard cause des soucis:

  • quelqu'un oublie de supprimer le code en pause avant de s'enregistrer
    • maintenant, tous les collègues de travail doivent se demander pourquoi l'application ne se ferme plus
    • l'historique des versions est corrompu
  • #define c'est l'enfer
  • c'est embêtant pour quiconque exécute votre code depuis la console
  • c'est très très ennuyant d'essayer de démarrer et de terminer votre programme à partir d'un script; quadly ennuyeux si votre programme fait partie d'un pipeline dans le shell, car si le programme ne se termine pas, le script shell ou le pipeline ne le sera pas non plus

Au lieu de cela, explorez votre IDE. Il a probablement une option pour ne pas fermer la fenêtre de la console après son exécution. Sinon, c'est une excellente justification pour vous en tant que développeur qui vaut son argent de toujours avoir une fenêtre de console ouverte à proximité.

Alternativement, vous pouvez en faire une option de programme, mais je n'ai personnellement jamais vu de programme avec une option --keep-alive-when-dead.

Morale de l'histoire: C'est le problème de l'utilisateur, pas le problème du programme. Ne souille pas votre code.

57
Sebastian Mach

Si vous voulez écrire du code C++ portable, je vous conseillerais alors d'utiliser cin.get().

system("PAUSE") fonctionne sous Windows, car il nécessite l'exécution d'une commande de console nommée "PAUSE". Mais je ne suis pas sûr que d’autres systèmes d’exploitation tels que Linux ou d’autres dérivés d’Unix le prennent en charge. Donc, cela a tendance à être non-portable.

Puisque C++ offre déjà cin.get(), je ne vois aucune raison impérieuse d’utiliser C getch().

16
Mr.C64

Quel est le meilleur moyen de mettre la console en pause dans les programmes C++?

system("pause"); et getch(); (qui proviennent du monde DOS, IIRC) sont tous deux inportables.

Est-il préférable d'utiliser cin.get () pour mettre la console en pause? 

En tant que seule option portable et standard , je dirais que oui, mais je pense personnellement qu’il ne faut pas écrire de programmes de console interactifs, c’est-à-dire des programmes qui mettent en pause la console ou qui invitent à entrer a vraiment une bonne raison pour cela, car cela rend les scripts Shell beaucoup plus difficiles). Les programmes de console devraient interagir avec l'utilisateur via des arguments de ligne de commande (ou au moins ce type d'interaction devrait être celui par défaut).

Juste au cas où vous auriez besoin de suspendre le programme pour que mon programme soit lancé à partir de l'IDE et immédiatement fermé, mais que je n'ai pas assez de temps pour voir les projets. résultat raison - ne fais pas ça. Il suffit de configurer votre IDE ou de lancer console programmes directement à partir de la console.

2
nameless

Il n'y a pas bon moyen de le faire, mais vous devriez utiliser une solution portable, évitez donc les appels system(); dans votre cas, vous pouvez utiliser cin.get() ou getch() comme vous l'avez mentionné dans votre question. Il existe également un conseil. Faites tous pauses contrôlées par une (ou très peu) définitions de préprocesseur.

Par exemple:

Quelque part dans le fichier global:

#define USE_PAUSES
#ifndef _DEBUG    //I asume you have _DEBUG definition for debug and don't have it for release build
#undef USE_PAUSES
#endif

Quelque part dans le code

#ifdef USE_PAUSES
cin.get();
#endif

Ce n'est pas un conseil universel, mais vous devriez vous protéger de mettre pauses dans les versions de release et celles-ci devraient être faciles à contrôler. Mon fichier global mentionné peut ne pas être aussi global, car des modifications dans ce domaine peuvent être très longues compilation.

2
ST3

Le meilleur moyen dépend beaucoup de la (des) plate-forme (s) ciblée (s), du débogage par rapport à l'utilisation de la version, etc.

Je ne pense pas qu'il existe un meilleur moyen, mais pour "forcer" un scénario de type attente de manière assez générique, en particulier lors du débogage (généralement compilé ou non en fonction de NDEBUG ou _DEBUG , vous pouvez essayer std::getline comme suit

inline void wait_on_enter()
{
    std::string dummy;
    std::cout << "Enter to continue..." << std::endl;
    std::getline(std::cin, dummy);
}

Avec notre sans "entrer pour continuer", au besoin. 

2
Niall

Cela fonctionne pour moi.

void pause()
{
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    std::string dummy;
    std::cout << "Press any key to continue . . .";
    std::getline(std::cin, dummy);
}
0
Yoank

Réponse tardive, mais je pense que cela aidera les autres.

Une partie du système imitant ("pause") imite ce qu’il demande à l’utilisateur de faire: "Appuyez sur n’importe quelle touche pour continuer." ) ferait. Même getch () a ses problèmes lorsqu'il est utilisé deux fois (on a remarqué que le deuxième appel évitait généralement les pauses s'il était immédiatement à nouveau placé sur la même touche). Je pense que cela a à voir avec le tampon d'entrée. System ("pause") n'est généralement pas recommandé, mais nous avons toujours besoin de quelque chose pour imiter ce à quoi les utilisateurs peuvent déjà s'attendre. Je préfère getch () car cela ne résonne pas à l'écran et fonctionne de manière dynamique. 

La solution consiste à effectuer les opérations suivantes à l'aide d'une boucle do-while:

void Console::pause()
{ 
    int ch = 0;

    std::cout << "\nPress any key to continue . . . ";

    do {
        ch = getch();
    } while (ch != 0);

    std::cout << std::endl;
} 

Il attend maintenant que l'utilisateur appuie sur une touche quelconque. S'il est utilisé deux fois, il attend à nouveau l'utilisateur au lieu de le sauter.

0
Bob

J'ai toujours utilisé quelques lignes de code pour effacer tous les caractères du flux d'entrée, puis attendre que l'entrée soit ignorée.

Quelque chose comme:

void pause() {
    cin.clear();
    cout << endl << "Press any key to continue...";
    cin.ignore();
}

Et puis chaque fois que j'en ai besoin dans le programme, j'ai ma propre pause (); fonction, sans la surcharge d'une pause système. Ce n'est vraiment un problème lorsque vous écrivez des programmes de la console que vous voulez rester ouvert ou rester concentré sur un certain point.

0
Eric Valero

(Ma réponse est partiellement basée sur celle de Yoank et partiellement sur un commentaire de Justin Time sur une autre question.)

cout << endl << "Press <Enter> to continue...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.get();
0
Marc.2377

Je veux juste ajouter qu'il existe un moyen d'obtenir ce que vous voulez, mais il faudra utiliser une bibliothèque tierce (ou que vous écriviez vous-même le code dépendant de la plate-forme).

En ce qui me concerne, le plus gros inconvénient de cin est que vous devez appuyer sur Return, et pas n'importe quelle clé. 

En supposant que vous ayez un écouteur clé, vous pourriez assez facilement écrire une fonction qui attend que l'utilisateur appuie sur la touche n'importe quelle touche. Cependant, trouver un auditeur de clé indépendant de la plate-forme n'est pas une tâche triviale et nécessitera très probablement de charger des parties d'une bibliothèque plus grande.

Je pense à quelque chose du genre:

char wait_for_key() {
    int key;
    while ( ! (key == key_pressed(ANY)) ) {
          this_thread::yield();
    }
    return convert_virtual_key_to_char(key);
}

La fonction réelle serait évidemment très différente de ce que j'ai écrit, selon la bibliothèque que vous utilisez.

Je sais que les bibliothèques suivantes ont des keylisteners (n'hésitez pas à en ajouter d'autres dans une édition si vous en connaissez.):

0
Stian V. Svedenborg