Wie kann das Konsolenfenster in Visual C ++ geöffnet bleiben?

191

Ich beginne mit Visual C ++ und möchte wissen, wie das Konsolenfenster beibehalten wird.

Zum Beispiel wäre dies eine typische "Hallo Welt" -Anwendung:

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

Was ist die Zeile, die ich vermisse?

Raúl Roa
quelle
Amruth A. Pillai Ihr Code zeigt nicht "Drücken Sie eine Taste, um fortzufahren" danke
Sie können das selbst mit einem einfachen std :: cout-Aufruf drucken.
Raúl Roa
5
Der Nachteil aller vorgeschlagenen Lösungen besteht darin, dass keine von ihnen mit dem Debuggen funktioniert (Strg + F5 schlägt hier fehl) und wenn die Anwendung unerwartet beendet wird (alle Haltepunkte oder Lesevorgänge von stdin bei der Hauptrückgabe schlagen hier fehl). Was ich gerne sehen würde, ist ein In-IDE-Konsolenfenster wie Eclipse und andere IDEs. Sie zeigen einfach die Ausgabe nach Beendigung des Programms stdout / stderr an.
dr. Sybren
@sybren Die akzeptierte Antwort funktioniert mit STRG + F5, und warum möchten Sie eine Lösung, die mit Debugging (F5) funktioniert? Sicherlich geht es beim Debuggen darum, ... zu debuggen? Was ist der Vorteil einer angehaltenen Konsole nach Beendigung des Programms in einer Debugging-Sitzung?
JBentley
2
Mit @JBentley Eclipse und anderen IDEs können Sie die Ausgabe Ihres Programms auch nach Beendigung des Prozesses lesen. Sicherlich sehen Sie den zusätzlichen Vorteil, insbesondere wenn Sie versuchen, einen Fehler zu finden? Ein Haltepunkt funktioniert auch nur, wenn Sie wissen, wo das Programm beendet wird. Dies kann schwer zu erkennen sein, wenn die Ausgabe von Ihrem Bildschirm verschwindet.
dr. Sybren

Antworten:

389

Starten Sie das Projekt mit Ctrl+F5statt nur F5.

Das Konsolenfenster bleibt nun mit der Press any key to continue . . .Meldung geöffnet , nachdem das Programm beendet wurde.

Beachten Sie, dass hierfür die Console (/SUBSYSTEM:CONSOLE)Linker-Option erforderlich ist , die Sie wie folgt aktivieren können:

  1. Öffnen Sie Ihr Projekt und rufen Sie den Projektmappen-Explorer auf. Wenn Sie mir in K & R folgen, lautet Ihre "Lösung" "Hallo" mit 1 Projekt darunter, auch "Hallo" in Fettdruck.
  2. Klicken Sie mit der rechten Maustaste auf "Hallo" (oder wie auch immer Ihr Projektname lautet.)
  3. Wählen Sie "Eigenschaften" aus dem Kontextmenü.
  4. Wählen Sie Konfigurationseigenschaften> Linker> System.
  5. Klicken Sie für die Eigenschaft "Subsystem" im rechten Bereich auf das Dropdown-Feld in der rechten Spalte.
  6. Wählen Sie "Konsole (/ SUBSYSTEM: CONSOLE)"
  7. Klicken Sie auf Übernehmen, warten Sie, bis der Vorgang abgeschlossen ist, und klicken Sie dann auf OK. (Wenn "Übernehmen" abgeblendet ist, wählen Sie eine andere Subsystemoption aus, klicken Sie auf Übernehmen und wenden Sie dann die Konsolenoption an. Meiner Erfahrung nach funktioniert OK an sich nicht.)

STRG-F5 und die Subsystemhinweise arbeiten zusammen. Sie sind keine separaten Optionen.

(Mit freundlicher Genehmigung von DJMorreTX von http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )

Zoidberg
quelle
36
Dadurch wird das Programm ohne Debugging ausgeführt. Es ist besser, eine Lösung zu haben, die sowohl im Debug- als auch im normalen Ausführungsmodus funktioniert.
ン ー パ.. ァ ァ ミ
3
Für alle, die diese Lösung nicht in einem Makefile-Projekt zum Laufen bringen können, liegt dies an einem Fehler in Visual Studio. Ich habe gerade eine Antwort mit dem Fix gepostet.
JBentley
1
Kann bestätigen! Hatte eine Konsolen-App, die nicht funktionierte, tat dies und es funktionierte. Sie müssen Ihren Code nicht mit cin.get(),getchar(), system("pause")oder anderen Müll ändern . Das zu ändern funktioniert.
Callat
Strg + F5 bedeutet "Ohne Debuggen starten". Sie können dies also nicht beim Debuggen verwenden. Fügen Sie einfach system("pause");am Ende Ihres Codes hinzu. Es macht Sinn und funktioniert gut.
Milad
41

Der Standardweg ist cin.get()vor Ihrer Rückgabeerklärung.

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    cin.get();
    return 0;
}
Gordon Wilson
quelle
4
Ich weiß, da das Programm bereits cout verwendet, dass es bereits erledigt wurde, aber ich denke, es lohnt sich zu erwähnen, dass Sie #include <iostream> sowie den std-Namespace verwenden müssen: std :: cin.get () .
Brian
7
Dies funktioniert, aber Strg + F5 ist viel besser, insbesondere wenn die globale Objektzerstörung usw. verfolgt wird.
Ternary
8
-1 für _tmain. Ich würde ein weiteres -1 für wählen, cin.get()anstatt einen Haltepunkt für F5 zu setzen oder Strg F5 zu verwenden. Aber ich darf nur einmal abstimmen.
Prost und hth. - Alf
8
@Cheers: Was ist los mit _tmain? Dies ist die Standardmethode zum Schreiben einer Windows-Anwendung für das Konsolensubsystem. Von diesem Standard abzuweichen, wäre eine schlechte Praxis. Es ist klar, dass hier niemand über tragbaren Code spricht. Die Frage lautet Visual C ++ und _tmainist die Signatur, die im Beispielcode angezeigt wird. Es ist Zeit, diese Religion aufzugeben. Windows ist standardmäßig "nicht standardisiert", und es gibt sehr gute Gründe, seinen Standards zu folgen .
Cody Gray
8
@CodyGray: Mein Downvote für _tmainist, weil es völlig unnötig ist, nicht dem Standard zu entsprechen (der internationale C ++ - Standard erfordert eine einfache Ebene main), und weil es das TMakroschema von Microsoft verwendet, das für die Unterstützung von Windows 9x unnötig kompliziert und ausführlich ist. Wenn Sie der Meinung sind, dass eine Abweichung vom Standard eine schlechte Praxis ist, sollten Sie diese unbedingt nicht verwenden tmain. Es gibt keine guten Gründe für die Verwendung tmain, außer für Trolling oder für Profis, um die totale Inkompetenz zu zeigen.
Prost und hth. - Alf
24

Setzen Sie einen Haltepunkt auf die returnLinie.

Sie führen es im Debugger aus, richtig?

Sam Harwell
quelle
15
Meistens schwierig, da es möglicherweise mehrere Ausstiegspunkte im Programm gibt
Volzotan
Das Programm startet möglicherweise nicht aufgrund fehlender DLL und erreicht diesen Haltepunkt nie
Michael
17

Eine andere Option ist zu verwenden

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

Dies ist zwar nicht sehr portabel, da es nur unter Windows funktioniert, aber automatisch gedruckt wird

Drücken Sie eine beliebige Taste, um fortzufahren...

Marcos Marin
quelle
1
System ("Pause") Lässt Ihren Prozessor laufen, sollte nicht verwendet werden. Verwenden Sie ein cin.get () oder ein gleichwertiges Element.
Krythic
systemwird in deklariert <stdlib.h>.
Melpomene
@ Krythic Ich habe es gerade versucht und es hat nicht 100% CPU gegessen. Mein Prozessorverbrauch lag die ganze Zeit bei 0% - 1%. Kann nicht reproduzieren.
Melpomene
Das System ("pause") ruft den Befehl "pause" in cmd auf, der die CPU NICHT ständig verwendet. Es entspricht im Wesentlichen _getche ().
Paul Stelian
7

Bei Makefile-Projekten schlägt die akzeptierte Lösung aufgrund eines Fehlers in Visual Studio fehl (der mindestens bis zur Version 2012 vorhanden ist - ich habe 2013 noch nicht getestet). Dieser Fehler wird hier detailliert beschrieben .

Führen Sie die folgenden Schritte aus, damit die Konsole nach dem Beenden des Programms in einem Makefile-Projekt angehalten wird (dies kann für andere Versionen als 2010 - 2012 abweichen):

1) /SUBSYSTEM:CONSOLEAn den Linker übergeben. - BEARBEITEN : siehe unten.

2) Öffnen Sie Ihre Projektdatei (.vcxproj) in einem Texteditor.

3) Fügen Sie in das Root- <project>Tag Folgendes ein:

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

4) Laden Sie das Projekt in Ihre Lösung neu.

5) Führen Sie das Programm ohne Debugging aus (STRG + F5).

BEARBEITEN:

Gemäß meinem Kommentar unten ist das Festlegen der Linker-Option /SUBSYSTEM:CONSOLEfür Makefile-Projekte eigentlich irrelevant (und nicht unbedingt sogar möglich, wenn Sie einen anderen Compiler als MSVC verwenden). Alles, was zählt, ist, dass die Einstellung der .vcxproj-Datei gemäß Schritt 3 oben hinzugefügt wird.

JBentley
quelle
Ich habe noch nie von Schritt 3 gehört. Bist du sicher, dass das erforderlich ist und funktioniert?
Mooing Duck
@mooingduck Ja, und nach meinen Kommentaren zu Ihrer Antwort hier habe ich jetzt festgestellt, dass die Weitergabe /SUBSYSTEM:CONSOLEan den Linker tatsächlich irrelevant ist - Schritt 3 ist alles, was zählt. Denken Sie daran, dass sich meine Antwort auf Makefile-Projekte bezieht. In einem Makefile-Projekt kann die IDE nicht wissen, was Sie an den Linker übergeben (möglicherweise verwenden Sie nicht einmal einen Compiler mit einer /SUBSYSTEM:CONSOLEOption), und es ist das Projekt selbst, die verfolgt, ob es sich um ein Konsolenprogramm handelt oder nicht. Ich werde meine Antwort entsprechend bearbeiten.
JBentley
1
@mooingduck Ich kann auch bestätigen, dass ich diese Lösung selbst in einem Makefile-Projekt mit SCons als Build-System und MSVC und MinGW als Compiler verwende. Ich kenne keine andere Möglichkeit, die IDE dazu zu bringen, die Konsole nach Beendigung im Nicht-Debugging-Modus anzuhalten.
JBentley
1
@chuckleplant Ich fürchte nicht, mein Workflow war umgekehrt und rief SCons von VS an. Ich habe meine VS-Makefile-Projekte zunächst manuell erstellt, damit sie Konfigurationsvariablen an mein SCons-Skript (z. B. 32/64 Bit, Compilername, Release / Debug) übergeben, das dann den Rest der Logik übernimmt. In diesem Setup mussten sich die Projektdateien nie ändern, daher habe ich keine automatisch generierende Funktion von SCons verwendet. Ich bin seitdem auf Linux umgestiegen, daher benutze ich VS nicht mehr. Da es sich um einen VS-Fehler handelt, kann es sinnvoll sein, eine Funktionsanforderung an SCons zu senden, um den erforderlichen zusätzlichen Schritt auszuführen.
JBentley
1
Alternativ können Sie einfach Python-Code in Ihr SCons-Skript aufnehmen, um dies jedes Mal selbst zu tun, wenn eine Projektdatei generiert wird. Ich glaube, dass VS-Projektdateien dem XML-Standard entsprechen, daher sollte es ziemlich einfach sein, die fehlenden Elemente hinzuzufügen, und es sollten nur wenige Codezeilen erforderlich sein. Ich würde vorschlagen, hier (für Python 2.x) oder hier (3.x) zu beginnen. Diese Antwort kann auch von Interesse sein.
JBentley
4

Sie können cin.get();oder cin.ignore();kurz vor Ihrer return-Anweisung verwenden, um zu verhindern, dass das Konsolenfenster geschlossen wird.

CMS
quelle
4

Setzen Sie einfach einen Haltepunkt auf die letzte geschweifte Klammer der Hauptleitung.

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

Es funktioniert für mich, es muss nicht ohne Debugging ausgeführt werden. Außerdem werden Destruktoren ausgeführt, bevor der Haltepunkt erreicht wird, sodass Sie überprüfen können, ob Nachrichten auf diesen Destruktoren gedruckt wurden, falls vorhanden.

Juan Castano
quelle
3

Fügen Sie einfach einen Haltepunkt in die schließende Klammer Ihrer _tmainMethode ein. Dies ist der einfachere Weg und Sie müssen keinen Code hinzufügen, um zu debuggen.

Odys
quelle
2

Setzen Sie einen Haltepunkt auf die Endklammer von main(). Es wird auch bei mehreren returnAnweisungen ausgelöst . Der einzige Nachteil ist, dass ein Anruf exit()nicht abgefangen wird.

Wenn Sie nicht debuggen, folgen Sie den Anweisungen in Zoidbergs Antwort und starten Sie Ihr Programm mit Ctrl+ F5anstatt nur F5.

Tschad
quelle
2

Meine 2 Cent:

Auswahl 1: Fügen Sie am Ende einen Haltepunkt hinzu main()

Auswahl 2: Fügen Sie diesen Code direkt vor dem 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');

Sie müssen enthalten <iomanip>fürstd::numeric_limits

Arnav Borborah
quelle
2

Fügen Sie einfach das System ("Pause") am Ende des Codes hinzu, bevor Sie 0 wie folgt zurückgeben

#include <stdlib.h>

int main()
{
    //some code goes here
    system("pause")
    return 0;
}
Melpomene
quelle
2
int main()
{
    //...
    getchar();
    return 0;
}
Gonnavis
quelle
2

cin.get()oder system("PAUSE"). Ich habe nicht gehört, dass Sie verwenden könnenreturn(0);

Udhav Sarvaiya
quelle
1

Ich #include <conio.h>füge hinzu und füge dann getch();kurz vor der return 0;Zeile hinzu. Das habe ich sowieso in der Schule gelernt. Die oben genannten Methoden sind ganz anders, wie ich sehe.

Amruth Pillai
quelle
2
-1: Abgesehen von der Tatsache, dass das Anhalten des Programms selbst normalerweise die falsche Lösung ist (da dies in den meisten Fällen nicht das Verhalten ist, das Ihre freigegebene Binärdatei haben soll), ist conio.h nicht standardisiert , veraltet und a C-Header, nicht C ++! Leider werden in Schulen viele schlechte Programmierpraktiken gelehrt.
JBentley
Man erwartet, dass dies nur während des Testens verwendet wird, es ist nicht etwas, das Sie in der endgültigen Version behalten würden. Wenn Sie für Windows programmieren, was ist das Problem mit #include <conio.h> / _getch ();? Es ist schneller zu schreiben als cin.get (), erfordert nicht das Drücken von 2 Tasten (mindestens ein Zeichen + Eingabe) und funktioniert nicht nur im Debug- oder nur im Release-Modus. Was ist dann los?
Barnack
1

Hatte das gleiche Problem. Ich benutze _getch()kurz vor der return-Anweisung. Es klappt.

Martin
quelle
Möglicherweise möchten Sie Ihrem Code Beispiele und Erklärungen hinzufügen, insbesondere für eine Frage, die vor langer Zeit gestellt / beantwortet wurde. Darüber hinaus ist Ihre Antwort funktional identisch mit mehreren älteren Antworten und verwendet denselben Anruf wie eine andere vorhandene Antwort.
Uhrwerk-Muse
0

(Einige Optionen können unter verschiedenen Namen aufgerufen werden. Ich verwende nicht die englische Version.)

Ich hatte das gleiche Problem, als ich Projekte mit der Option "leeres Projekt" erstellte, Projekt als "Win32-Konsolenanwendung" anstelle von "leeres Projekt" erstellen. In dem Dialogfeld, das jetzt angezeigt wird, drücken Sie "Weiter". Danach können Sie die Option "Projekt leeren" aktivieren und auf "Bestätigen" klicken. Danach öffnet STRG + F5 eine Konsole, die nicht automatisch geschlossen wird.

Blechdose
quelle
0

Ich hatte das gleiche Problem; In meiner Anwendung gibt es mehrere exit () - Punkte und es gab keine Möglichkeit zu wissen, wo genau es beendet wird. Dann habe ich Folgendes herausgefunden:

atexit(system("pause"));

oder

atexit(cin.get());

Auf diese Weise wird es gestoppt, egal wo wir im Programm beenden.

Charaf Errachidi
quelle
Keiner dieser Anrufe ist gültig atexit. atexitNimmt einen Funktionszeiger, keine ganze Zahl.
Melpomene
0

Andere Option:

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

In der Hauptsache:

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

Die eigentliche Lösung ist die Auswahl der Projektvorlage. Sie MÜSSEN die Win32-Konsolenanwendung in älterem VS auswählen oder zuerst den Projektnamen eingeben und dann auf den Windows-Desktop-Assistenten doppelklicken und dann die Win32-Konsolenanwendung auswählen. Wählen Sie dann an dieser Stelle ein leeres Projekt aus. Dies ermöglicht dann, was der ursprüngliche Fragesteller wirklich wollte, ohne zusätzlichen Haltepunkt hinzuzufügen und Code zu halten. Ich habe auch dieses Problem durchlaufen. Die Antwort ist auch auf der MSDN-Site.

user9416431
quelle
0

Hier ist eine Möglichkeit, das Befehlsfenster offen zu halten, unabhängig davon, wie die Ausführung gestoppt wird, ohne dass Code geändert wird:

Öffnen Sie in Visual Studio Projekteigenschaftsseiten -> Debuggen .

Geben Sie als Befehl ein$(ComSpec)

Geben Sie als Befehlsargumente ein /k $(TargetPath). Fügen Sie Ihrer eigenen Anwendung Argumente hinzu.

Jetzt F5 oder Strg-F5 führt windows / system32 / cmd.exe in einem neuen Fenster und / k sichergestellt , dass die Eingabeaufforderung bleibt nach Abschluss der Ausführung öffnen.

Der Nachteil ist, dass die Ausführung an Haltepunkten nicht stoppt.

Jonathan Lidbeck
quelle
0

Wie einige bereits betont haben, hängt die Zoidbergs-Lösung den Debugger nicht an, was Sie normalerweise nicht möchten.

Die beste Option imo ist, Ihren VS entsprechend zu konfigurieren (ab VS 2017), indem Sie zu Extras> Optionen> Debugging> Allgemein gehen. Dort deaktivieren Sie "Konsole automatisch schließen, wenn das Debuggen beendet wird" (ganz unten), was in Ihrem Fall wahrscheinlich aktiviert ist.

iko79
quelle
-1

Sie können einfach keep_window_open () setzen; vor der Rückkehr hier ist ein Beispiel

int main()
{
    cout<<"hello world!\n";
    keep_window_open ();
    return 0;
}
Sifis Babionitakis
quelle
2
Woher kommt keep_window_open (), z. B. welche Header-Datei und Bibliothek?
Tom Goodfellow
Es ist von diesem std_lib_facilities.h, aber die meiste Zeit haben Sie es enthalten
Sifis Babionitakis