Jak zatrzymać natychmiastowe zamykanie aplikacji konsoli C ++?

193

Ostatnio próbowałem nauczyć się C ++ z tej strony . Niestety, ilekroć próbuję uruchomić jeden z przykładów kodu, widzę, że ten program jest otwarty na około pół sekundy, a następnie natychmiast się zamyka. Czy jest jakiś sposób, aby zatrzymać natychmiastowe zamykanie programu, abym mógł zobaczyć owoce mojego wysiłku?

Adam P.
źródło
5
Czy klikasz dwukrotnie plik wykonywalny? Czy pracujesz w systemie Windows? Dlaczego nie pracujesz z poziomu powłoki poleceń i nie wpisujesz poleceń tak, jak chcesz je wykonać?
S.Lott
8
@S Lott: Ponieważ jeśli naciśniesz przycisk „Go” w swoim IDE, nie musisz zawracać sobie głowy konsolą.
Billy ONeal
4
Powinieneś rozważyć zdobycie dobrej książki do nauki języka C ++. Strony internetowe to dobre zasoby, ale nie mogą się równać z dobrym tekstem wprowadzającym. Ostateczna lista książek w C ++ tutaj: stackoverflow.com/questions/388242/...
James McNellis
6
@Billy Jeśli naciśnięcie przycisku Go zamyka aplikację po jej zakończeniu, używasz niewłaściwego IDE.
2
Pytanie i odpowiedź poprzednio tutaj: stackoverflow.com/questions/902261/… , chociaż ten ma lepszy tytuł.
dmckee --- były moderator kociak

Odpowiedzi:

121

Edycja: Jak słusznie zauważa Charles Bailey w komentarzu poniżej, nie zadziała to, jeśli buforowane są postacie stdini naprawdę nie ma dobrego sposobu na obejście tego. Jeśli korzystasz z podłączonego debugera, sugerowane rozwiązanie Johna Diblinga jest prawdopodobnie najczystszym rozwiązaniem twojego problemu.

Powiedziawszy, zostawię to tutaj i może ktoś inny uzna to za przydatne. Używałem go często jako szybkiego hacka podczas pisania testów podczas programowania.


Po zakończeniu mainfunkcji możesz zadzwonićstd::getchar();

Otrzyma to pojedynczy znak stdin, co da ci zachowanie „naciśnij dowolny klawisz, aby kontynuować” (jeśli naprawdę chcesz otrzymać komunikat „naciśnij dowolny klawisz”, musisz sam go wydrukować).

Trzeba #include <cstdio>za getchar.

James McNellis
źródło
15
getcharnie rozwiązuje problemu - przynajmniej w ograniczonych okolicznościach. Odczytuje znak z stdin, ale jeśli są już znaki buforowane ze standardowego wejścia, program będzie kontynuował bez czekania, niezależnie od tego, czy wydrukujesz monit, czy nie.
CB Bailey
1
@Charles: Dobra uwaga. Ignorowanie dopóki \njest częściowym rozwiązaniem, ale nie pomoże, jeśli buforowany jest więcej niż jeden wiersz danych wejściowych. Nie znam standardowego sposobu C ++, aby wyczyścić wszystko ze strumienia wejściowego. : - /
James McNellis
1
@James: Stary, ale co powiesz na std::cin.ignore(std::cin.rdbuf()->in_avail());? Mam to stąd .
GManNickG
1
Jedną z opcji jest dużo używam std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');z #include <limits>.
Xeo 29.01.11
5
Proszę nie rób tego. :( Nie jest to częścią funkcji twojego programu.
Lightness Races in Orbit
138

Jeśli używasz Visual Studio i uruchamiasz aplikację konsolową z IDE:

naciśnięcie CTRL-F5 (uruchom bez debugowania) uruchomi aplikację i pozostanie otwarte okno konsoli, dopóki nie naciśniesz żadnego klawisza.

nabulke
źródło
1
Uruchamianie konsoli z IDE? Jak i dlaczego miałbyś to zrobić?
CodyBugstein,
1
Doskonale, działało. Dlaczego nie jest to domyślne zachowanie programu Visual Studio?
Oprawa
Pomyślałem również, że tak to robi, aż do dziś, kiedy buduję prosty program konsoli i powyższa metoda nie działa :(
KansaiRobot
1
Czy istnieje wersja tego z debugowaniem?
luckyging3r
109

Rozwiązanie Jamesa działa na wszystkich platformach.

Alternatywnie Windowsmożesz także dodać następujące przed powrotem z mainfunkcji:

  system("pause");

Spowoduje to uruchomienie pausepolecenia czekającego na naciśnięcie klawisza, a także wyświetlenie miłej wiadomościPress any key to continue . . .

kodaddict
źródło
2
To brzmi jak wariant rozwiązania Rube Goldberga.
Dave Van den Eynde
4
@Dave Van den Eynde: Jest to również dość powszechne i jest standardem w kodzie bojlerów w DevCPP. +1
Billy ONeal
4
Z drugiej strony @Dave wyjaśnia, że ​​jest to na przykład bodge, podczas gdy std: getch może zostać przypadkowo pozostawiony w prawdziwym kodzie.
Martin Beckett
2
Jest to całkowicie poprawne rozwiązanie dla osób korzystających z systemu Windows. Chociaż nie jest idealny, to działa
thecoshman 10.10.12
Najłatwiejsze, najszybsze rozwiązanie. Właśnie tego potrzebowałem
CodyBugstein
83

Jeśli używasz programu Microsoft Visual C ++ 2010 Express i napotykasz problem z tym, że CTRL + F5 nie działa w celu utrzymania konsoli otwartej po zakończeniu programu, spójrz na ten wątek MSDN .

Prawdopodobnie IDE jest skonfigurowane do zamykania konsoli po uruchomieniu CTRL + F5; w rzeczywistości „Pusty projekt” w Visual C ++ 2010 domyślnie zamyka konsolę. Aby to zmienić, wykonaj czynności sugerowane przez moderatora Microsoft:

Kliknij prawym przyciskiem myszy nazwę projektu i przejdź do strony Właściwości, rozwiń Właściwości konfiguracji -> Łącznik -> System, wybierz Konsolę (/ PODSYSTEM: KONSOLA) w menu rozwijanym Podsystem. Ponieważ domyślnie Pusty projekt tego nie określa.

Mr. Underhill
źródło
1
Co jeśli nie jest to aplikacja na konsolę?
Jesse Pepper
3
@ Mr.Underhill To zadziała tylko wtedy, gdy uruchomisz bez debuggera (Ctrl + F5).
Jonathan Mee,
Oprócz tego, że jest to jedyne rozwiązanie niehakujące, jest to również jedyny sposób, aby zobaczyć odbitki z niszczycieli obiektów stosu głównego.
Poniros
20

Zazwyczaj po prostu stawiam punkt przerwania na main()zamykającym się nawiasie klamrowym. Kiedy koniec programu zostanie osiągnięty w jakikolwiek sposób, punkt przerwania uderzy i możesz ALT-Tab w oknie konsoli, aby wyświetlić wynik.

John Dibling
źródło
14

Dlaczego po prostu nie uruchomić programu z konsoli, tj. Uruchomić program z cmd.exe, jeśli używasz systemu Windows. W ten sposób okno pozostaje otwarte po zakończeniu programu.

[EDYCJA]: Kiedy używam KDevelop4, istnieje pełnoprawna instancja Bash (Linux CLI) działająca na zakładce na dole IDE. Tego używam w takich okolicznościach.

Amos
źródło
3
Ponieważ jeśli używasz IDE, zazwyczaj nie używasz konsoli. Naciskasz go, program działa i to wszystko.
Billy ONeal
3
Każde kompetentne IDE będzie wyświetlać konsolę na ekranie, gdy aplikacja się zakończy - na przykład Code :: Blocks właśnie to robi.
3
@nobugz: Zrozumiałem. Aby okno pozostało, musisz mieć / SUBSYSTEM: CONSOLE w wierszu poleceń konsolidatora. Dokumentacja mówi, że jest to ustawienie domyślne, jeśli mainjest zdefiniowane, ale jeśli nie ustawię go jawnie w wierszu poleceń, VS zabija okno po zamknięciu aplikacji. westchnienie
James McNellis
2
@James: jest to wymagane, aby uzyskać okno konsoli. To z kolei wymaga main () zamiast WinMain (), a nie na odwrót. Jestem trochę zagubiony ...
Hans Passant
4
@nobugz: Jeśli zaczynasz od „Pustego projektu” zamiast „aplikacji konsoli Win32”, podsystem nie jest jawnie ustawiony we właściwościach projektu. Jeśli zdefiniujesz mainw projekcie, konsolidator domyślnie korzysta z podsystemu CONSOLE. Podczas debugowania lub uruchamiania pojawi się okno konsoli. Jednakże, chyba że wyraźnie podasz CONSOLE jako podsystem we właściwościach projektu, Visual Studio nie utrzyma otwartego okna konsoli. Zawsze zaczynam od pustego projektu i rzadko zmieniam właściwości poszczególnych projektów, więc nigdy nie widziałem, żeby okno konsoli się zatrzymało. Przepraszamy za zamieszanie
James McNellis
9

Przed końcem kodu wstaw następujący wiersz:

system("pause");

Pozwoli to zachować konsolę do momentu naciśnięcia klawisza.

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s;
    cout << "Please enter your first name followed by a newline\n";
    cin >> s;
    cout << "Hello, " << s << '\n';
    system("pause"); // <----------------------------------
    return 0; // This return statement isn't necessary
}
Robert
źródło
Wydrukowano także „Naciśnij dowolny klawisz, aby kontynuować.” dla mnie.
PapaHotelPapa
8

Zadzwoń cin.get();2 razy:

    //...
    cin.get();
    cin.get();
    return 0
}
tsx
źródło
6
ale dlaczego dwa razy?
Madhawa Priyashantha
co jeśli potrzebujemy kolejnej funkcji cin.get () do uzyskania na przykład jakiegoś ciągu znaków wewnątrz tablicy? W tym scenariuszu nie działa.
QMaster
4

Jeśli uruchomisz kod z kompetentnego IDE, takiego jak Code :: Blocks , IDE będzie zarządzać konsolą używaną do uruchamiania kodu, pozostawiając go otwartym po zamknięciu aplikacji. Nie chcesz dodawać specjalnego kodu, aby utrzymać konsolę otwartą, ponieważ uniemożliwi to jej poprawne działanie, gdy będziesz używać jej naprawdę poza IDE.


źródło
3

Okej, zgaduję, że korzystasz z systemu Windows za pomocą programu Visual Studio ... dlaczego? Cóż, ponieważ jeśli masz system operacyjny Linux, prawdopodobnie uruchomiłbyś go z konsoli.

W każdym razie możesz dodać bzdury na koniec programu, jak sugerują inni, lub możesz po prostu nacisnąć CTRL + F5 (zacznij bez debugowania), a Visual Studio opuści konsolę po zakończeniu.

Inną opcją, jeśli chcesz uruchomić wersję Debugowania i nie dodawać bzdur do kodu, jest otwarcie okna konsoli (Start -> Uruchom -> cmd) i przejście do katalogu wyjściowego Debugowania . Następnie wystarczy wpisać nazwę pliku wykonywalnego, aby uruchomić program do debugowania w konsoli. Następnie możesz użyć programu Visual Studio do dołączania do przetwarzania lub czegoś takiego, jeśli naprawdę chcesz.

Polaris878
źródło
3
#include "stdafx.h"
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{

    cout << "Press any key to continue...";
    getch();

    return 0;
}

Nie zauważyłem, że ktoś to opublikował, więc oto jest.

Ruan
źródło
Dodam, że conio.hjest to nagłówek specyficzny dla systemu Windows i może nie być dostępny na każdym komputerze (lub być może trzeba go połączyć osobno, co jest przesadą).
Yksisarvinen
Pracujący. po prostu potrzebowałem zmienić getch (); do _getch (); od czasu jego utraty
ncesar
2

Jeśli faktycznie debugujesz aplikację w Visual C ++, naciśnij klawisz F5 lub zielony trójkąt na pasku narzędzi. Jeśli tak naprawdę nie debugujesz go (nie masz ustawionych punktów przerwania), naciśnij Ctrl + F5 lub wybierz z menu opcję Rozpocznij bez debugowania (zwykle jest to menu Debugowanie, które, jak się zgadzam, jest mylące). Będzie trochę szybciej, i co ważniejsze dla ciebie, zatrzyma się na końcu bez konieczności zmiany kodu.

Możesz też otworzyć wiersz polecenia, przejść do folderu, w którym znajduje się plik exe, i uruchomić go, wpisując jego nazwę. W ten sposób po zakończeniu uruchamiania wiersz polecenia nie zamyka się i można wyświetlić wynik. Wolę obie te metody od dodania kodu, który zatrzymuje aplikację po zakończeniu.

Kate Gregory
źródło
2

Po prostu dodaj poniższe na końcu programu. Spróbuje przechwycić jakąś formę danych wejściowych użytkownika, dzięki czemu konsola nie zostanie automatycznie zamknięta.

cin.get();
Bat_Programmer
źródło
2

Dodaj następujące wiersze przed dowolną exit()funkcją lub przed dowolnym returnw main():

std::cout << "Paused, press ENTER to continue." << std::endl;
cin.ignore(100000, "\n");
Thomas Matthews
źródło
Dla mnie to nie działa, pierwsza linia działa, ale naciśnięcie Enter nic nie robi
Qwertie
2

W przypadku programu Visual Studio (i tylko Visual Studio) następujący fragment kodu wyświetla monit o „poczekanie na naciśnięcie klawisza, aby kontynuować”, który naprawdę czeka na wyraźne naciśnięcie nowego klawisza przez użytkownika, najpierw opróżniając bufor wejściowy:

#include <cstdio>
#include <tchar.h>
#include <conio.h>

_tprintf(_T("Press a key to continue "));
while( _kbhit() /* defined in conio.h */ ) _gettch();
_gettch();

Zauważ, że dzięki temu tchar.hmakra są kompatybilne z wieloma „zestawami znaków” (jak je nazywa VC ++).

MicroVirus
źródło
2

Po prostu to robię:

//clear buffer, wait for input to close program
std::cin.clear(); std::cin.ignore(INT_MAX, '\n');
std::cin.get();
return 0;

Uwaga: wyczyszczenie bufora cin i takie jest konieczne tylko wtedy, gdy użyłeś cin w pewnym momencie wcześniej w swoim programie. Również użycie std :: numeric_limits :: max () jest prawdopodobnie lepsze niż INT_MAX, ale jest nieco nieporadne i zwykle niepotrzebne.

GuestPerson00001
źródło
Działa, ale zwraca 0; nie uruchomi się, jeśli użyję tego kodu.
wernersbacher
2

Użyj #include "stdafx.h"i system("pause");tak jak kod poniżej.

#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
    std::cout << "hello programmer!\n\nEnter 2 numbers: ";
    int x, y;
    std::cin >> x >> y;
    int w = x*y;
    std::cout <<"\nyour answer is: "<< w << endl;
    system("pause");
}
Mohammed Nouh
źródło
systemjest zadeklarowany w <cstdlib>, nie stdafx.h.
melpomene
1

Podobny pomysł Yeh odpowiedź, tylko minimalistyczny alternatywą.

Utwórz plik wsadowy o następującej treści:

helloworld.exe
pause

Następnie użyj pliku wsadowego.

Cœur
źródło
1

po prostu

#include <cstdio>

    int main(){
        // code...
        std::getchar();
        std::getchar();
        return 0;
    }

z jakiegoś powodu zwykle jest możliwe odczytanie 1 znaku za pomocą getchar już w standardowym czasie uruchamiania programu. więc pierwszy getchar odczytuje ten znak, a drugi getchar czeka na dane wejściowe użytkownika (twojego) przed wyjściem z programu. A po wyjściu programu z większości terminali, szczególnie w systemie Windows natychmiast zamknij terminal. dlatego naszym celem jest prosty sposób zapobiegania zakończeniu programu po wypisaniu wszystkiego. Oczywiście istnieją bardziej złożone i czyste sposoby rozwiązania tego, ale jest to najprostszy.

Dmitrij Suserov
źródło
2
Dodaj przynajmniej krótkie wyjaśnienie, dlaczego to rozwiązuje problem.
kaya3
0

Sprawdź, czy IDE ma pole wyboru w ustawieniach projektu, aby okno pozostało otwarte po zakończeniu programu. Jeśli nie, użyj, std::cin.get();aby odczytać znak na końcu głównej funkcji. Pamiętaj jednak, aby używać wyłącznie wprowadzania liniowego (std :: getline) lub w przeciwnym razie radzić sobie z pozostałymi nieprzeczytanymi znakami (std :: ignoruj ​​do nowej linii), ponieważ w przeciwnym razie .get () na końcu odczyta tylko śmieci, które pozostawiłeś nieprzeczytane wcześniej.

Tronic
źródło
0

To wydaje się działać dobrze:

cin.clear();
cin.ignore(2);

Jeśli najpierw wyczyścisz bufor, nie będzie problemu podczas czytania następnego. Z jakiegoś powodu cin.ignore(1)nie działa, musi być 2.

Northcode
źródło
1
Czasami 2 również nie wystarcza (gdy w kolejce jest więcej naciśnięć klawiszy). Prawidłowym sposobem jest zignorowanie tylu znaków, ile jest w kolejce. Do z cin.rdbuf()->in_avail,. Żadna magiczna liczba jak 1 lub 2.
Konrad Rudolph
0

Zawsze możesz po prostu utworzyć plik wsadowy. Na przykład, jeśli Twój program nazywa się helloworld.exe, kod może wyglądać następująco:

@echo off
:1
cls
call helloworld.exe
pause >nul
goto :1
tak
źródło
0

Jeśli używasz systemu Windows, możesz zrobić system("pause >nul");lub system("pause");. Wykonuje polecenie konsoli, aby wstrzymać program do momentu naciśnięcia klawisza. >nulzapobiega temu Press any key to continue....

PatThaCoder
źródło
0

Stawiam punkt przerwania przy ostatnim zwrocie 0 programu. To działa dobrze.

lierosk
źródło
1
To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienie, zostaw komentarz pod jego postem - zawsze możesz komentować własne posty, a gdy będziesz mieć wystarczającą reputację , będziesz mógł komentować każdy post .
Ravi Dhoriya ツ
1
Jak to nie zapewnia odpowiedzi? Jestem w dokładnie takiej samej sytuacji jak autor pytania, a to pomaga.
lierosk
0

Użyłem cin.get()i to działa, ale pewnego dnia musiałem użyć innego cin.get([Array Variable]), aby złapać sznur molwy z pustym znakiem na środku. więc cin.get()nie uniknęło zamknięcia okna wiersza polecenia. Wreszcie znalazłem inny sposób: naciśnij CTRL + F5, aby otworzyć w oknie zewnętrznym, a Visual Studio nie ma już nad nim kontroli. Poprosi Cię tylko o zamknięcie po uruchomieniu ostatecznych poleceń.

QMaster
źródło
0

Próbowałem umieścić getchar()funkcję na końcu. Ale to nie zadziałało. Więc dodałem dwie getchar()funkcje jedna po drugiej. Myślę, że pierwszy getchar()wchłania Enterklawisz, który naciskasz po ostatnim wprowadzeniu danych. Spróbuj więc dodać dwie getchar()funkcje zamiast jednej

Nathan Tuggy
źródło
0

Zamiast naciskać przycisk Uruchom, naciśnij jednocześnie CTRL i F5, da ci to dowolny klawisz, aby kontynuować wiadomość. Lub wpisz „(ostrzeżenie użyj tego tylko do testowania nie rzeczywistych programów, ponieważ antywirusy tego nie lubią !!!!)” na końcu swojej głównej funkcji, ale: (ostrzeżenie użyj tego tylko do testowania nie rzeczywistych programów jako antywirusów to ci się podoba !!!!)

anony
źródło
0

po prostu użyj cin.ignore () tuż przed zwróceniem 0; dwa razy

main()
  {
  //your codes 

  cin.ignore();
  cin.ignore();

  return 0;
  }

to wszystko

Kursat Turkay
źródło
Zwykle robię to coś takiego. cin.ignore (); cin.get ();
aj.toulan
-1

Wszystko, co musisz zrobić, to ustawić zmienną dla x, a następnie po prostu wpisać ją przed wartością 0;

cout<<"\nPress any key and hit enter to end...";
cin>>x;
Przyjazna rada
źródło
-1

Możesz nawet zadeklarować liczbę całkowitą na początku swojej main()funkcji (powiedzmy int a;) i umieścić std::cin >> a;tuż przed wartością zwracaną. Tak więc program będzie działał, dopóki nie naciśniesz klawisza i nie wprowadzisz.

Izza
źródło