Comment garder la fenêtre de la console ouverte dans Visual C ++?


191

Je débute dans Visual C ++ et j'aimerais savoir comment conserver la fenêtre de la console.

Par exemple, ce serait une application typique "bonjour le monde":

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    return 0;
}

Quelle est la ligne qui me manque?


Amruth A. Pillai votre code ne montre pas "appuyez sur n'importe quelle touche pour continuer" merci

Vous pouvez l'imprimer vous-même avec un simple appel std :: cout.
Raúl Roa du

5
L'inconvénient de toutes les solutions proposées est qu'aucune d'entre elles ne fonctionne avec le débogage (Ctrl + F5 échoue ici) et lorsque l'application s'arrête de manière inattendue (tous les points d'arrêt ou les lectures de stdin au retour principal échouent ici). Ce que j'aimerais voir, c'est une fenêtre de console in-IDE comme Eclipse et d'autres IDE. Ils continuent simplement à afficher la sortie vers stdout / stderr après la fin du programme.
dr. Sybren

@sybren La réponse acceptée fonctionne avec CTRL + F5, et pourquoi voudriez-vous une solution qui fonctionne avec le débogage (F5)? Le point entier du débogage est sûrement de… déboguer? Quel est l'avantage d'avoir une console en pause après l'arrêt du programme, dans une session de débogage?
JBentley

2
@JBentley Eclipse et d'autres IDE vous permettent de lire la sortie de votre programme même après la fin du processus. Vous voyez sûrement l'avantage supplémentaire, en particulier lorsque vous essayez de trouver un bogue? De plus, un point d'arrêt ne fonctionne que lorsque vous savez où le programme se termine, ce qui peut être difficile à dire lorsque la sortie disparaît de votre écran.
dr. Sybren

Réponses:


389

Démarrez le projet avec Ctrl+F5au lieu de simplement F5.

La fenêtre de la console restera désormais ouverte avec le Press any key to continue . . .message après la fermeture du programme.

Notez que cela nécessite l' Console (/SUBSYSTEM:CONSOLE)option de l' éditeur de liens, que vous pouvez activer comme suit:

  1. Ouvrez votre projet et accédez à l'Explorateur de solutions. Si vous me suivez dans K&R, votre "Solution" sera "bonjour" avec 1 projet en dessous, également "bonjour" en gras.
  2. Faites un clic droit sur le "bonjour" (ou quel que soit le nom de votre projet.)
  3. Choisissez "Propriétés" dans le menu contextuel.
  4. Choisissez Propriétés de configuration> Éditeur de liens> Système.
  5. Pour la propriété "Sous-système" dans le volet de droite, cliquez sur la liste déroulante dans la colonne de droite.
  6. Choisissez "Console (/ SUBSYSTEM: CONSOLE)"
  7. Cliquez sur Appliquer, attendez qu'il ait fini de faire ce qu'il fait, puis cliquez sur OK. (Si «Appliquer» est grisé, choisissez une autre option de sous-système, cliquez sur Appliquer, puis revenez en arrière et appliquez l'option de console. Mon expérience est que OK en soi ne fonctionnera pas.)

CTRL-F5 et les conseils de sous-système fonctionnent ensemble; ce ne sont pas des options distinctes.

(Gracieuseté de DJMorreTX de http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )


36
Cela exécute le programme sans débogage; il est préférable d'avoir une solution qui fonctionne à la fois en mode débogage et en mode d'exécution ordinaire.
ス ー パ ー フ ァ ミ コ ン

3
Pour toute personne qui ne peut pas faire fonctionner cette solution dans un projet makefile, cela est dû à un bogue dans Visual Studio. Je viens de publier une réponse avec le correctif.
JBentley

1
Peut confirmer! Une application console qui ne fonctionnait pas a fait cela et cela a fonctionné. Vous n'avez pas besoin de modifier votre code avec cin.get(),getchar(), system("pause")ou tout autre garbage. Changer cela fonctionne.
Callat le

Ctrl + F5 signifie «Démarrer sans débogage». Vous ne pouvez donc pas l'utiliser lors du débogage. Ajoutez simplement system("pause");à la fin de votre code. Cela a du sens et fonctionne bien.
Milad

41

La méthode standard est cin.get()avant votre déclaration de retour.

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    cin.get();
    return 0;
}

4
Je sais que depuis que le programme utilise déjà cout, il a déjà été pris en charge, mais je pense qu'il vaut la peine de mentionner que vous devrez #include <iostream> et utiliser l'espace de noms std: std :: cin.get () .
Brian

7
Cela fonctionne mais le Ctrl + F5 est bien meilleur surtout lors du traçage de la destruction globale des objets, etc.
Ternaire

8
-1 pour _tmain. Je voterais un autre -1 pour le cin.get()au lieu de placer un point d'arrêt pour F5 ou d'utiliser Ctrl F5. Mais je n'ai droit qu'à un vote défavorable.
Bravo et hth. - Alf

8
@Cheers: Quel est le problème _tmain? C'est la manière standard d'écrire une application Windows ciblant le sous-système de la console. S'écarter de cette norme serait une mauvaise pratique. De toute évidence, personne ne parle de code portable ici; la question indique Visual C ++ et _tmainest la signature qui apparaît dans l'exemple de code. Il est temps d'abandonner cette religion. Windows est "non standard" par défaut, et il existe de très bonnes raisons de suivre ses standards.
Cody Gray

8
@CodyGray: Mon vote défavorable pour _tmainest parce qu'il est totalement non standard (le standard international C ++ nécessite un simple main), et parce qu'il utilise le Tschéma de macro de Microsoft , qui est une complication et un verbiage inutiles pour prendre en charge Windows 9x. Si vous pensez que s'écarter de la norme est une mauvaise pratique, vous ne devez absolument pas l'utiliser tmain. Il n'y a pas de bonnes raisons d'utiliser tmain, sauf pour la pêche à la traîne ou, pour les professionnels, pour afficher son incompétence totale.
Bravo et hth. - Alf

24

Mettez un point d'arrêt sur la returnligne.

Vous l'exécutez dans le débogueur, non?


15
la plupart du temps difficile car il peut y avoir plusieurs points de sortie à l'intérieur du programme
volzotan

Le programme peut ne pas démarrer en raison d'une DLL manquante et ne jamais atteindre ce point d'arrêt
Michael

18

Une autre option consiste à utiliser

#include <process.h>
system("pause");

Bien que ce ne soit pas très portable car il ne fonctionnera que sur Windows, mais il imprimera automatiquement

Appuyez sur n'importe quelle touche pour continuer...


1
system ("pause") Gardera votre processeur en marche, il ne devrait pas être utilisé. Utilisez un cin.get () ou équivalent.
Krythic

systemest déclaré dans <stdlib.h>.
melpomene

@Krythic Je viens de l'essayer et il n'a pas mangé 100% de CPU. Mon utilisation du processeur était à 0% - 1% tout le temps. Ne peut pas reproduire.
melpomene

system ("pause") appellera la commande "pause" dans cmd, qui n'utilise PAS le CPU tout le temps. C'est essentiellement équivalent à _getche ().
Paul Stelian

7

Pour les projets makefile, la solution acceptée échoue, en raison d'un bogue dans Visual Studio (qui est présent au moins jusqu'à la version 2012 - je n'ai pas encore testé 2013). Ce bug est détaillé ici .

Afin de mettre la console en pause après la fin du programme sur un projet makefile, procédez comme suit (cela peut différer pour les versions autres que 2010-2012):

1) Passez /SUBSYSTEM:CONSOLEà l'éditeur de liens. - MODIFIER : voir ci-dessous.

2) Ouvrez votre fichier projet (.vcxproj) dans un éditeur de texte.

3) À l'intérieur de la <project>balise racine , insérez ce qui suit:

<ItemDefinitionGroup>
  <Link>
    <SubSystem>Console</SubSystem>
  </Link>
</ItemDefinitionGroup>

4) Rechargez le projet dans votre solution.

5) Exécutez le programme sans débogage (CTRL + F5).

ÉDITER:

Selon mon commentaire ci-dessous, la définition de l'option de l'éditeur de liens /SUBSYSTEM:CONSOLEn'est en fait pas pertinente pour les projets makefile (et pas nécessairement même possible, si vous utilisez un compilateur autre que MSVC). Tout ce qui compte, c'est que le paramètre soit ajouté au fichier .vcxproj, comme indiqué à l'étape 3 ci-dessus.


Je n'ai jamais entendu parler de cette étape 3 auparavant. Vous êtes sûr que cela est nécessaire et fonctionne?
Mooing Duck

@mooingduck Oui, et après mes commentaires sur votre réponse ici , j'ai maintenant découvert que le passage /SUBSYSTEM:CONSOLEà l'éditeur de liens n'est en fait pas pertinent - l'étape 3 est tout ce qui compte. Gardez à l'esprit que ma réponse concerne les projets makefile - dans un projet makefile, l'EDI n'a aucun moyen de savoir ce que vous passez à l'éditeur de liens (vous n'utilisez peut-être même pas un compilateur qui a une /SUBSYSTEM:CONSOLEoption), et c'est le projet lui-même qui garde une trace de si oui ou non il est censé être un programme de console. Je modifierai ma réponse en conséquence.
JBentley

1
@mooingduck Je peux également confirmer que j'utilise moi-même cette solution dans un projet makefile, avec SCons comme système de construction et MSVC et MinGW comme compilateurs. Il n'y a pas d'autre moyen que je connaisse pour que l'EDI suspende la console après l'arrêt en mode sans débogage.
JBentley

1
@chuckleplant Je crains que non, mon flux de travail était l'inverse, appelant SCons de VS. J'ai initialement créé manuellement mes projets makefile VS afin qu'ils passent des variables de configuration à mon script SCons (par exemple 32/64 bits, nom du compilateur, version / débogage), qui a ensuite géré le reste de la logique. Dans cette configuration, il n'était pas nécessaire que les fichiers du projet changent, je n'ai donc utilisé aucune fonctionnalité de génération automatique de SCons. Depuis, je suis passé à Linux donc je n'utilise plus VS. Puisqu'il s'agit d'un bogue VS, il peut être intéressant de soumettre une demande de fonctionnalité à SCons pour gérer l'étape supplémentaire requise.
JBentley

1
Sinon, vous pouvez simplement inclure du code Python dans votre script SCons pour le faire vous-même chaque fois qu'un fichier de projet est généré. Je pense que les fichiers de projet VS sont conformes à la norme XML, il devrait donc être assez facile d'ajouter les éléments manquants et ne devrait nécessiter que quelques lignes de code. Je suggérerais de commencer ici (pour Python 2.x) ou ici (3.x). Cette réponse peut également être intéressante.
JBentley

4

Vous pouvez utiliser cin.get();ou cin.ignore();juste avant votre déclaration de retour pour éviter que la fenêtre de la console ne se ferme.


4

il suffit de mettre un point d'arrêt sur la dernière parenthèse de main.

    int main () {
       //...your code...
       return 0;
    } //<- breakpoint here

cela fonctionne pour moi, pas besoin de courir sans débogage. Il exécute également des destructeurs avant d'atteindre le point d'arrêt afin que vous puissiez vérifier tous les messages imprimés sur ces destructeurs si vous en avez.


3

Ajoutez simplement un point d'arrêt à la parenthèse fermante de votre _tmainméthode. C'est le moyen le plus simple et vous n'avez pas besoin d'ajouter de code pour déboguer.


2

Placez un point d'arrêt sur l'accolade de fin de main(). Il sera déclenché même avec plusieurs returndéclarations. Le seul inconvénient est qu'un appel à exit()ne sera pas pris.

Si vous n'êtes pas en train de déboguer, suivez les conseils de la réponse de Zoidberg et démarrez votre programme avec Ctrl+ F5au lieu de simplement F5.


2

Mes 2 cents:

Choix 1: ajouter un point d'arrêt à la fin de main()

Choix 2: ajoutez ce code, juste avant le return 0;:

std::cout << "Press ENTER to continue..."; //So the User knows what to do
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Vous devez inclure <iomanip>pourstd::numeric_limits


2

ajoutez simplement le système ("pause") à la fin du code avant de retourner 0 comme ceci

#include <stdlib.h>

int main()
{
    //some code goes here
    system("pause")
    return 0;
}


2

cin.get(), ou system("PAUSE"). Je n'ai pas entendu que vous pouvez utiliserreturn(0);


1

J'inclus #include <conio.h>et ensuite, j'ajoute getch();juste avant la return 0;ligne. C'est ce que j'ai appris à l'école de toute façon. Les méthodes mentionnées ci-dessus ici sont assez différentes, je vois.


2
-1: Mis à part le fait que la mise en pause du programme lui-même est généralement la mauvaise solution (car dans la plupart des cas, ce n'est pas le comportement que vous voulez que votre binaire publié ait), conio.h est non standard , obsolète et est un En-tête C, pas C ++! Malheureusement, de nombreuses mauvaises pratiques de programmation sont enseignées dans les écoles.
JBentley

On s'attend à ce que cela ne soit utilisé que pendant les tests, ce n'est pas quelque chose que vous conserverez dans la version finale. Si vous codez pour Windows, quel est le problème avec #include <conio.h> / _getch () ;? Il est plus rapide à écrire que cin.get (), ne nécessite pas d'appuyer sur 2 touches (au moins un caractère + entrée) et ne fonctionne pas uniquement en débogage ou uniquement en mode version. Qu'est-ce qui ne va pas alors?
Barnack

1

Avait le même problème. J'utilise _getch()juste avant l'instruction de retour. Ça marche.


Vous pouvez ajouter des exemples et des explications à votre code, en particulier pour une question posée / répondue il y a si longtemps. De plus, votre réponse est fonctionnellement identique à plusieurs réponses plus anciennes et utilise le même appel qu'une autre réponse existante.
Clockwork-Muse

0

(Certaines options peuvent être appelées par des noms différents. Je n'utilise pas la version anglaise)

J'ai eu le même problème, quand j'ai créé des projets avec l'option "projet vide", Créer un projet comme "application Win32-console" au lieu de "projet vide". Dans la boîte de dialogue qui apparaît maintenant, vous appuyez sur "continuer" et après cela vous pouvez cocher l'option "projet vide" et appuyer sur confirmer. Après cela, CTRL + F5 ouvrira une console qui ne se ferme pas automatiquement.


0

J'ai eu le même problème; Dans mon application, il y a plusieurs points exit () et il n'y avait aucun moyen de savoir exactement où il sort, alors j'ai découvert ceci:

atexit(system("pause"));

ou

atexit(cin.get());

De cette façon, il s'arrêtera peu importe où nous sortirons du programme.


Aucun de ces appels n'est valide atexit. atexitprend un pointeur de fonction, pas un entier.
melpomene

0

Une autre option:

#ifdef _WIN32
#define MAINRET system("pause");return 0
#else
#define MAINRET return 0
#endif

En général:

int main(int argc, char* argv[]) {
    MAINRET;
}

0

En fait, la vraie solution est la sélection du modèle de projet lui-même. Vous DEVEZ sélectionner l'application console Win32 dans les anciens VS, ou remplir d'abord le nom du projet, puis double-cliquer sur l'assistant Windows Desktop, puis sélectionner l'application console Win32. Sélectionnez ensuite un projet vide à ce stade. Cela permet alors ce que le questionneur d'origine voulait vraiment sans ajouter de point d'arrêt supplémentaire et de code de maintien. J'ai également traversé ce problème. La réponse est également sur le site MSDN.


0

Voici un moyen de garder la fenêtre de commande ouverte quelle que soit la façon dont l'exécution s'arrête sans modifier le code:

Dans Visual Studio, ouvrez les pages de propriétés du projet -> Débogage .

Pour Commande , entrez$(ComSpec)

Pour les arguments de commande , entrez/k $(TargetPath) . Ajoutez des arguments à votre propre application.

Maintenant F5 ou Ctrl-F5 exécute Windows / System32 / cmd.exe dans une nouvelle fenêtre, et / k garantit que l'invite de commande reste ouverte une fois l'exécution terminée.

L'inconvénient est que l'exécution ne s'arrêtera pas aux points d'arrêt.


0

Comme certains l'ont déjà souligné, la solution Zoidbergs n'attache pas le débogueur, ce que vous ne voulez généralement pas.

La meilleure option imo est de configurer votre VS en conséquence (à partir de VS 2017), en allant dans Outils> Options> Débogage> Général. Là, vous décochez "Fermer automatiquement la console lorsque le débogage s'arrête" (tout en bas), ce qui est probablement coché dans votre cas.


-1

vous pouvez simplement mettre keep_window_open (); avant le retour voici un exemple

int main()
{
    cout<<"hello world!\n";
    keep_window_open ();
    return 0;
}

2
D'où vient keep_window_open (), par exemple de quel fichier d'en-tête et de quelle bibliothèque?
Tom Goodfellow

son de celui-ci std_lib_facilities.h mais la plupart du temps vous l'avez inclus
Sifis Babionitakis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.