Come mantenere aperta la finestra della console in Visual C ++?


191

Sto iniziando in Visual C ++ e vorrei sapere come mantenere la finestra della console.

Ad esempio questa sarebbe una tipica applicazione "ciao mondo":

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

Qual è la linea che mi manca?


Amruth A. Pillai il tuo codice non mostra "premi nessun tasto per continuare" grazie

Puoi stamparlo tu stesso con una semplice chiamata std :: cout.
Raúl Roa,

5
L'aspetto negativo di tutte le soluzioni proposte è che nessuna di esse funziona con il debug (qui Ctrl + F5 non riesce) e quando l'applicazione si interrompe in modo imprevisto (tutti i punti di interruzione o le letture da stdin al ritorno principale falliscono qui). Quello che mi piacerebbe vedere è una finestra della console in-IDE come Eclipse e altri IDE. Continuano semplicemente a mostrare l'output su stdout / stderr dopo che il programma è terminato.
dott. Sybren,

@sybren La risposta accettata funziona con CTRL + F5 e perché vorresti una soluzione che funzioni con il debug (F5)? Sicuramente il punto di debug è ... debug? Qual è il vantaggio di avere una console in pausa dopo la fine del programma, in una sessione di debug?
JBentley,

2
@JBentley Eclipse e altri IDE ti consentono di leggere l'output del tuo programma anche dopo che il processo è stato terminato. Sicuramente vedi il vantaggio aggiunto, specialmente quando cerchi di trovare un bug? Inoltre, un punto di interruzione funziona solo quando sai dove sta finendo il programma, il che può essere difficile da dire quando l'output scompare dallo schermo.
dott. Sybren,

Risposte:


389

Inizia il progetto con Ctrl+F5invece di solo F5.

La finestra della console rimarrà aperta con il Press any key to continue . . .messaggio dopo la chiusura del programma.

Nota che questo richiede l' Console (/SUBSYSTEM:CONSOLE)opzione linker, che puoi abilitare come segue:

  1. Apri il tuo progetto e vai a Esplora soluzioni. Se stai seguendo con me in K&R, la tua "Soluzione" sarà "ciao" con 1 progetto sotto di esso, e anche "ciao" in grassetto.
  2. Fai clic con il tasto destro del mouse su "ciao" (o qualunque sia il nome del tuo progetto.)
  3. Scegli "Proprietà" dal menu contestuale.
  4. Scegli Proprietà di configurazione> Linker> Sistema.
  5. Per la proprietà "Sottosistema" nel riquadro di destra, fare clic sulla casella a discesa nella colonna di destra.
  6. Scegli "Console (/ SUBSYSTEM: CONSOLE)"
  7. Fai clic su Applica, attendi che finisca di fare qualsiasi cosa faccia, quindi fai clic su OK. (Se "Applica" è disattivato, scegli qualche altra opzione del sottosistema, fai clic su Applica, quindi torna indietro e applica l'opzione console. La mia esperienza è che OK da solo non funzionerà.)

CTRL-F5 e i suggerimenti del sottosistema funzionano insieme; non sono opzioni separate.

(Per gentile concessione di DJMorreTX da http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )


36
Questo esegue il programma senza debug; è meglio avere una soluzione che funzioni sia in debug che in modalità di esecuzione ordinaria.
ス ー パ ー フ ァ ミ コ ン

3
Per chiunque non riesca a far funzionare questa soluzione in un progetto makefile, ciò è dovuto a un bug in Visual Studio. Ho appena pubblicato una risposta con la correzione.
JBentley,

1
Posso confermare! Aveva un'app console che non funzionava e funzionava. Non è necessario modificare il codice con cin.get(),getchar(), system("pause")o altri rifiuti. Cambiando questo funziona.
Callat,

Ctrl + F5 significa "Avvia senza debug". Quindi non puoi usarlo durante il debug. Aggiungi solo system("pause");alla fine del codice. Ha senso e funziona bene.
Milad,

41

Il modo standard è cin.get()prima della dichiarazione di reso.

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

4
So che dal momento che il programma sta già utilizzando Cout di cui è già stato curato, ma penso che valga la pena menzionare che sarà necessario #include <iostream> e utilizzare lo spazio dei nomi std: std :: cin.get () .
Brian,

7
Funziona ma Ctrl + F5 è molto meglio soprattutto quando si traccia la distruzione di oggetti globali, ecc.
Ternary,

8
-1 per _tmain. Vorrei votare un altro -1 per cin.get()invece di posizionare un breakpoint per F5 o usando Ctrl F5. Ma ho solo un voto negativo.
Saluti e hth. - Alf

8
@Cheers: Cosa c'è che non va _tmain? Questo è il modo standard per scrivere un'applicazione Windows destinata al sottosistema Console. Deviare da quello standard è quella che sarebbe una cattiva pratica. Chiaramente, nessuno parla di codice portatile qui; la domanda dice Visual C ++ ed _tmainè la firma che appare nel codice di esempio. È tempo di abbandonare questa religione. Windows è "non standard" per impostazione predefinita e ci sono ottime ragioni per seguire i suoi standard.
Cody Gray

8
@CodyGray: il mio downvote per _tmainè perché non è assolutamente necessario non standard (lo standard internazionale C ++ richiede un semplice main) e perché utilizza lo Tschema macro di Microsoft , che è inutile complicazione e verbosità per il supporto di Windows 9x. Se ti senti deviare dallo standard è una cattiva pratica, allora non dovresti assolutamente usarlo tmain. Non ci sono buoni motivi per usare tmain, tranne che per la pesca a traina o, per i professionisti, per mostrare la propria incompetenza totale.
Saluti e hth. - Alf

24

Metti un punto di interruzione sul return linea.

Lo stai eseguendo nel debugger, giusto?


15
la maggior parte delle volte è difficile in quanto potrebbero esserci più punti di uscita all'interno del programma
volzotan,

Il programma potrebbe non avviarsi a causa della mancanza di DLL e non raggiungere mai quel punto di interruzione
Michael

18

Un'altra opzione è usare

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

Anche se questo non è molto portatile perché funzionerà solo su Windows, ma verrà stampato automaticamente

Premere un tasto qualsiasi per continuare...


1
system ("pause") Manterrà il tuo processore in esecuzione, non dovrebbe essere usato. Usa un cin.get () o equivalente.
Krythic,

systemè dichiarato in <stdlib.h>.
melpomene,

@Krythic L'ho appena provato e non ha mangiato CPU al 100%. Il mio processore è stato utilizzato allo 0% - 1% per tutto il tempo. Impossibile riprodurre.
melpomene,

system ("pause") chiamerà il comando "pause" in cmd, che NON utilizza sempre la CPU. È equivalente a _getche () essenzialmente.
Paul Stelian,

7

Per i progetti di makefile, la soluzione accettata non riesce, a causa di un bug in Visual Studio (che è presente almeno fino alla versione 2012 - Non ho ancora testato il 2013). Questo bug è dettagliato qui .

Per fare in modo che la console venga messa in pausa dopo la conclusione del programma su un progetto makefile, procedere come segue (ciò può differire per le versioni diverse da 2010-2012):

1) Passa /SUBSYSTEM:CONSOLEal linker. - EDIT : vedi sotto.

2) Apri il tuo file di progetto (.vcxproj) in un editor di testo.

3) All'interno del <project>tag radice , inserire quanto segue:

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

4) Ricarica il progetto nella tua soluzione.

5) Eseguire il programma senza debug (CTRL + F5).

MODIFICARE:

Secondo il mio commento qui sotto, l'impostazione dell'opzione linker /SUBSYSTEM:CONSOLEè in realtà irrilevante per i progetti di makefile (e non necessariamente nemmeno possibile, se si utilizza un compilatore diverso da MSVC). Tutto ciò che conta è che l'impostazione venga aggiunta al file .vcxproj, come indicato al passaggio 3 sopra.


Non ho mai sentito parlare di quel passaggio 3 prima. Sei sicuro che sia richiesto e funzioni?
Mooing Duck,

@mooingduck Sì, e dopo i miei commenti sulla tua risposta qui , ho scoperto che passare /SUBSYSTEM:CONSOLEal linker è in realtà irrilevante: il passaggio 3 è tutto ciò che conta. Tieni presente che la mia risposta riguarda i progetti di makefile: in un progetto di makefile, l'IDE non ha modo di sapere cosa stai passando al linker (potresti non usare nemmeno un compilatore che ha /SUBSYSTEM:CONSOLEun'opzione), ed è il progetto stesso che tiene traccia del fatto che debba essere o meno un programma console. Modificherò di conseguenza la mia risposta.
JBentley,

1
@mooingduck Posso anche confermare che uso questa soluzione da solo in un progetto makefile, con SCons come sistema di compilazione e MSVC e MinGW come compilatori. Non conosco altro modo per far sì che l'IDE metta in pausa la console dopo la chiusura in modalità non di debug.
JBentley,

1
@chuckleplant Temo di no, il mio flusso di lavoro è stato il contrario, chiamando SCons da VS. Inizialmente ho creato manualmente i miei progetti makefile VS in modo che passassero le variabili di configurazione al mio script SCons (ad es. 32/64 bit, nome del compilatore, versione / debug), che quindi ha gestito il resto della logica. In quella configurazione non era necessario che i file di progetto cambiassero mai, quindi non ho usato nessuna funzione di generazione automatica di SCons. Da allora sono passato a Linux, quindi non uso più VS. Poiché si tratta di un bug VS, potrebbe valere la pena di inviare una richiesta di funzionalità a SCons per gestire il passaggio aggiuntivo richiesto.
JBentley,

1
In alternativa, potresti semplicemente includere un po 'di codice Python nello script di SCons per farlo da solo ogni volta che viene generato un file di progetto. Credo che i file di progetto VS siano conformi allo standard XML, quindi dovrebbe essere abbastanza facile aggiungere gli elementi mancanti e dovrebbe richiedere solo poche righe di codice. Suggerirei di iniziare qui (per Python 2.x) o qui (3.x). Questa risposta potrebbe anche essere di interesse.
JBentley,

4

È possibile utilizzare cin.get();o cin.ignore();appena prima della dichiarazione di ritorno per evitare la chiusura della finestra della console.


4

basta mettere un breakpoint sull'ultima parentesi graffa del main.

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

funziona per me, non c'è bisogno di correre senza debug. Esegue anche i distruttori prima di colpire il punto di interruzione, in modo da poter controllare l'eventuale stampa dei messaggi su questi distruttori.


3

Aggiungi semplicemente un Breakpoint alla parentesi di chiusura del tuo _tmainmetodo. Questo è il modo più semplice, inoltre non è necessario aggiungere codice per eseguire il debug.


2

Posizionare un punto di interruzione sul controvento finale di main(). Verrà inciampato anche con più returndichiarazioni. L'unico aspetto negativo è che una chiamata aexit() non verrà catturata.

Se non stai eseguendo il debug, segui i consigli nella risposta di Zoidberg e avvia il tuo programma con Ctrl+ F5anziché solo F5.


2

I miei 2 centesimi:

Scelta 1: aggiungere un punto di interruzione alla fine di main()

Scelta 2: aggiungi questo codice, subito prima di 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');

Devi includere <iomanip>perstd::numeric_limits


2

basta aggiungere il sistema ("pausa") alla fine del codice prima di restituire 0 in questo modo

#include <stdlib.h>

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



1

Includo #include <conio.h>e poi aggiungo getch();poco prima della return 0;riga. Questo è quello che ho imparato a scuola comunque. I metodi sopra menzionati qui sono abbastanza diversi che vedo.


2
-1: A parte il fatto che avere il programma stesso in pausa è di solito la soluzione sbagliata (poiché nella maggior parte dei casi questo non è il comportamento che si desidera avere il proprio binario rilasciato), conio.h non è standard , è obsoleto ed è un Intestazione C, non C ++! Sfortunatamente, ci sono molte cattive pratiche di programmazione insegnate nelle scuole.
JBentley,

Ci si aspetta che questo venga usato solo durante i test, non è qualcosa che manterresti nella versione finale. Se stai codificando per Windows qual è il problema con #include <conio.h> / _getch () ;? È veloce per scrivere rispetto a cin.get (), non richiede di premere 2 tasti (almeno un carattere + invio) e non funziona solo in debug o solo in modalità di rilascio. Cosa c'è che non va allora?
Barnack,

1

Ho avuto lo stesso problema. Sto usando _getch()poco prima della dichiarazione di ritorno. Funziona.


Potresti voler aggiungere esempi e spiegazioni al tuo codice, in particolare per una domanda posta / risposta molto tempo fa. Inoltre, la risposta è funzionalmente identica a diverse risposte precedenti e utilizza la stessa chiamata di un'altra risposta esistente.
Clockwork-Muse

0

(Alcune opzioni possono essere chiamate con nomi diversi. Non utilizzo la versione inglese)

Ho avuto lo stesso problema, quando ho creato progetti con l'opzione "progetto vuoto", Crea progetto come "Applicazione console Win32" anziché "Progetto vuoto". Nella finestra di dialogo che si apre ora, premi "continua" e successivamente puoi selezionare l'opzione "progetto vuoto" e premere conferma. Successivamente CTRL + F5 aprirà una console che non si chiude automaticamente.


0

Ho avuto lo stesso problema; Nella mia applicazione ci sono più punti exit () e non c'era modo di sapere dove esattamente esca, quindi ho scoperto questo:

atexit(system("pause"));

o

atexit(cin.get());

In questo modo si fermerà, non importa dove usciamo dal programma.


Nessuno di questi sono chiamate valide a atexit. atexitaccetta un puntatore a funzione, non un numero intero.
melpomene,

0

Un'altra opzione:

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

In linea di principio:

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

0

In realtà, la vera soluzione è la selezione del modello di progetto stesso. È NECESSARIO selezionare l'applicazione console Win32 nella versione precedente di VS, oppure inserire prima il nome del progetto, quindi fare doppio clic sulla procedura guidata Desktop di Windows, quindi selezionare l'applicazione console Win32. Quindi selezionare il progetto vuoto a questo punto. Ciò consente quindi ciò che l'interrogatore originale desiderava davvero senza aggiungere ulteriore punto di arresto e trattenere il codice. Ho attraversato anche questo problema. La risposta è anche sul sito MSDN.


0

Ecco un modo per mantenere aperta la finestra di comando indipendentemente da come si interrompe l'esecuzione senza modificare alcun codice:

In Visual Studio, apri le pagine delle proprietà del progetto -> Debug .

Per Comando , immettere$(ComSpec)

Per Argomenti comando , immettere/k $(TargetPath) . Aggiungi eventuali argomenti alla tua domanda.

Ora F5 o Ctrl-F5 esegue Windows / System32 / cmd.exe in una nuova finestra e / k garantisce che il prompt dei comandi rimanga aperto al termine dell'esecuzione.

Il rovescio della medaglia è che l'esecuzione non si fermerà sui punti di interruzione.


0

Come alcuni hanno già sottolineato, la soluzione Zoidbergs non collega il debugger, cosa che di solito non si desidera.

La migliore opzione imo è quella di configurare il tuo VS di conseguenza (dal VS 2017 in poi), andando su Strumenti> Opzioni> Debug> Generale. Lì deselezioni "Chiudi automaticamente la console quando il debug si arresta" (in fondo), che è probabilmente spuntato nel tuo caso.


-1

puoi semplicemente mettere keep_window_open (); prima del ritorno qui c'è un esempio

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

2
Da dove viene keep_window_open (), ad es. Quale file di intestazione e libreria?
Tom Goodfellow,

è da questo std_lib_facilities.h ma la maggior parte delle volte ce l'hai incluso
Sifis Babionitakis
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.