Jak utrzymać otwarte okno konsoli w Visual C ++?

191

Zaczynam od Visual C ++ i chciałbym wiedzieć, jak zachować okno konsoli.

Na przykład byłaby to typowa aplikacja „hello world”:

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

Jakiego wiersza mi brakuje?

Raúl Roa
źródło
Amruth A. Pillai Twój kod nie pokazuje „naciśnij dowolny klawisz, aby kontynuować” dzięki
Możesz wydrukować to sam za pomocą prostego wywołania std :: cout.
Raúl Roa,
5
Wadą wszystkich proponowanych rozwiązań jest to, że żadne z nich nie działa przy debugowaniu (Ctrl + F5 tutaj się nie udaje) i gdy aplikacja zatrzymuje się nieoczekiwanie (wszystkie punkty przerwania lub odczyty ze standardowego powrotu podczas głównego powrotu zawodzą tutaj). Chciałbym zobaczyć okno konsoli w IDE, takie jak Eclipse i inne IDE. Po prostu wyświetlają wynik na stdout / stderr po zakończeniu programu.
dr. Sybren,
@sybren Akceptowana odpowiedź działa z CTRL + F5 i dlaczego miałbyś chcieć rozwiązania współpracującego z debugowaniem (F5)? Z pewnością sednem debugowania jest ... debugowanie? Jakie są korzyści z zatrzymania konsoli po zakończeniu programu w sesji debugowania?
JBentley,
2
@JBentley Eclipse i inne środowiska IDE pozwalają czytać dane wyjściowe programu nawet po zakończeniu procesu. Z pewnością widzisz dodatkową korzyść, zwłaszcza gdy próbujesz znaleźć błąd? Również punkt przerwania działa tylko wtedy, gdy wiesz, gdzie kończy się program, co może być trudne do ustalenia, kiedy wyjście zniknie z ekranu.
dr. Sybren,

Odpowiedzi:

389

Rozpocznij projekt Ctrl+F5zamiast zamiast F5.

Okno konsoli pozostanie otwarte z Press any key to continue . . .komunikatem po wyjściu z programu.

Pamiętaj, że wymaga to Console (/SUBSYSTEM:CONSOLE)opcji linkera, którą możesz włączyć w następujący sposób:

  1. Otwórz swój projekt i przejdź do Eksploratora rozwiązań. Jeśli podążasz za mną w K&R, Twoim „rozwiązaniem” będzie „cześć” z 1 projektem pod nim, a także „cześć” pogrubioną czcionką.
  2. Kliknij prawym przyciskiem myszy „cześć” (lub dowolną nazwę projektu).
  3. Wybierz „Właściwości” z menu kontekstowego.
  4. Wybierz Właściwości konfiguracji> Linker> System.
  5. Aby wyświetlić właściwość „Podsystem” w prawym panelu, kliknij menu rozwijane w prawej kolumnie.
  6. Wybierz „Console (/ SUBSYSTEM: CONSOLE)”
  7. Kliknij Zastosuj, poczekaj, aż skończy to, co robi, a następnie kliknij OK. (Jeśli opcja „Zastosuj” jest wyszarzona, wybierz inną opcję podsystemu, kliknij przycisk Zastosuj, a następnie wróć i zastosuj opcję konsoli. Z mojego doświadczenia wynika, że ​​sama OK nie zadziała).

CTRL-F5 i wskazówki do podsystemu działają razem; nie są osobnymi opcjami.

(Dzięki uprzejmości DJMorreTX z http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )

Zoidberg
źródło
36
Spowoduje to uruchomienie programu bez debugowania; lepiej jest mieć rozwiązanie, które działa zarówno w trybie debugowania, jak i zwykłym.
ス ー パ ー フ ァ ミ コ ン
3
Dla każdego, kto nie może zmusić tego rozwiązania do pracy w projekcie makefile, jest to spowodowane błędem w Visual Studio. Właśnie opublikowałem odpowiedź z poprawką.
JBentley
1
Potwierdź! Aplikacja na konsolę, która nie działała, działała i działała. Nie musisz zmieniać kodu za pomocą cin.get(),getchar(), system("pause")ani innych śmieci. Zmiana tego działa.
Callat
Ctrl + F5 oznacza „Rozpocznij bez debugowania”. Więc nie możesz tego użyć podczas debugowania. Po prostu dodaj system("pause");na końcu swojego kodu. Ma to sens i działa dobrze.
Milad
41

Standardowy sposób jest cin.get()przed zwrotem.

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    cin.get();
    return 0;
}
Gordon Wilson
źródło
4
Wiem, ponieważ program już używa cout, że już się nim zajęto, ale myślę, że warto wspomnieć, że musisz #include <iostream>, a także użyć przestrzeni nazw std: std :: cin.get () .
Brian
7
To działa, ale Ctrl + F5 jest znacznie lepszy, szczególnie gdy śledzi globalne zniszczenie obiektów itp.
Ternary
8
-1 dla _tmain. Głosowałbym na kolejne -1 cin.get()zamiast zamiast punktu przerwania dla F5 lub używania Ctrl F5. Ale wolno mi tylko jedna opinia.
Pozdrawiam i hth. - Alf
8
@Cheers: Co jest nie tak _tmain? Jest to standardowy sposób pisania aplikacji Windows ukierunkowanej na podsystem konsoli. Odbieganie od tego standardu byłoby złym postępowaniem. Oczywiście nikt nie mówi o przenośnym kodzie; pytanie brzmi Visual C ++ i _tmainjest sygnaturą, która pojawia się w przykładowym kodzie. Czas porzucić tę religię. Windows jest domyślnie „niestandardowy” i istnieją bardzo dobre powody, aby stosować się do jego standardów.
Cody Gray
8
@CodyGray: Moje poparcie dla _tmainjest spowodowane tym, że jest to całkowicie niepotrzebne niestandardowe (międzynarodowy standard C ++ wymaga zwykłego main) i ponieważ wykorzystuje Tschemat makr Microsoftu , który jest niepotrzebną komplikacją i językiem do obsługi systemu Windows 9x. Jeśli czujesz, że odstępstwo od standardu jest złą praktyką, absolutnie nie powinieneś używać tmain. Nie ma dobrych powodów do używania tmain, z wyjątkiem trollingu lub, dla profesjonalistów, do wykazania całkowitej niekompetencji.
Pozdrawiam i hth. - Alf
24

Umieść punkt przerwania na returnlinii.

Używasz go w debuggerze, prawda?

Sam Harwell
źródło
15
w większości przypadków trudne, ponieważ w programie może być wiele punktów wyjścia
volzotan
Program może się nie uruchomić z powodu braku biblioteki DLL i nigdy nie trafić w ten punkt przerwania
Michael
18

Inną opcją jest użycie

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

Chociaż nie jest to zbyt przenośne, ponieważ będzie działać tylko w systemie Windows, ale zostanie automatycznie wydrukowane

Naciśnij dowolny klawisz, aby kontynuować...

Marcos Marin
źródło
1
system („pauza”) Utrzyma działanie procesora, nie należy go używać. Użyj cin.get () lub odpowiednika.
Krythic
systemjest zadeklarowany w <stdlib.h>.
melpomene
@ Krythic Właśnie próbowałem i nie zjadłem 100% procesora. Moje użycie procesora wynosiło 0% - 1% przez cały czas. Nie można odtworzyć.
melpomene
system („pause”) wywoła polecenie „pause” w cmd, które NIE używa procesora przez cały czas. Zasadniczo jest to odpowiednik _getche ().
Paul Stelian
7

W przypadku projektów makefile zaakceptowane rozwiązanie kończy się niepowodzeniem z powodu błędu w programie Visual Studio (który jest obecny przynajmniej do wersji 2012 - nie testowałem jeszcze 2013). Ten błąd jest szczegółowo opisany tutaj .

Aby zatrzymać konsolę po zakończeniu programu w projekcie makefile, wykonaj następujące kroki (może się to różnić w przypadku wersji innych niż 2010-2012):

1) Przejdź /SUBSYSTEM:CONSOLEdo linkera. - EDYCJA : patrz poniżej.

2) Otwórz plik projektu (.vcxproj) w edytorze tekstu.

3) Wewnątrz <project>znacznika głównego wstaw następujące elementy:

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

4) Załaduj ponownie projekt do swojego rozwiązania.

5) Uruchom program bez debugowania (CTRL + F5).

EDYTOWAĆ:

Zgodnie z moim komentarzem poniżej ustawienie opcji linkera /SUBSYSTEM:CONSOLEjest w rzeczywistości nieistotne dla projektów makefile (i niekoniecznie nawet możliwe, jeśli używasz kompilatora innego niż MSVC). Liczy się tylko to, że ustawienie zostanie dodane do pliku .vcxproj, jak w kroku 3 powyżej.

JBentley
źródło
Nigdy wcześniej nie słyszałem o tym kroku 3. Jesteś pewien, że jest to wymagane i działa?
Mooing Duck
@mooingduck Tak i po moich komentarzach do twojej odpowiedzi tutaj odkryłem, że przekazanie /SUBSYSTEM:CONSOLElinkerowi jest w rzeczywistości nieistotne - liczy się tylko krok 3. Pamiętaj, że moja odpowiedź dotyczy projektów makefile - w projekcie makefile IDE nie ma sposobu, aby dowiedzieć się, co przekazujesz linkerowi (możesz nawet nie używać kompilatora, który ma /SUBSYSTEM:CONSOLEopcję), a jest to projekt sam, który śledzi, czy ma być programem konsolowym. Odpowiednio zmienię swoją odpowiedź.
JBentley
1
@mooingduck Mogę również potwierdzić, że sam używam tego rozwiązania w projekcie makefile, z SCons jako systemem kompilacji, a MSVC i MinGW jako kompilatorami. Nie ma innego sposobu, aby przekonać IDE do wstrzymania konsoli po zakończeniu pracy w trybie innym niż debugowanie.
JBentley
1
@chuckleplant Obawiam się, że nie, mój przepływ pracy był odwrotny, nazywając SCons z VS. Początkowo ręcznie utworzyłem moje projekty plików makefile VS, aby przekazywały zmienne konfiguracyjne do mojego skryptu SCons (np. 32/64 bit, nazwa kompilatora, wydanie / debugowanie), które następnie obsługiwały resztę logiki. W tej konfiguracji nie było potrzeby zmiany plików projektu, więc nie użyłem żadnej funkcji automatycznego generowania SConów. Od tego czasu przeszedłem na Linuksa, więc nie używam już VS. Ponieważ jest to błąd VS, warto przesłać żądanie SCons do obsługi wymaganego dodatkowego kroku.
JBentley,
1
Alternatywnie, możesz po prostu dodać trochę kodu Python do skryptu SCons, aby zrobić to sam za każdym razem, gdy generowany jest plik projektu. Uważam, że pliki projektu VS są zgodne ze standardem XML, więc dodanie brakujących elementów powinno być dość łatwe i powinno wymagać tylko kilku wierszy kodu. Sugerowałbym zacząć tutaj (dla Python 2.x) lub tutaj (3.x). Ta odpowiedź może być również interesująca.
JBentley,
4

Możesz użyć cin.get();lub cin.ignore();tuż przed instrukcją return, aby uniknąć zamknięcia okna konsoli.

CMS
źródło
4

po prostu umieść punkt przerwania na ostatnim kręconym nawiasie głównym.

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

działa dla mnie, nie ma potrzeby uruchamiania bez debugowania. Wykonuje także destruktory przed trafieniem do punktu przerwania, dzięki czemu można sprawdzić wszelkie komunikaty wydrukowane na tych destrukterach, jeśli takie istnieją.

Juan Castano
źródło
3

Po prostu dodaj punkt przerwania do nawiasu zamykającego _tmainmetody. Jest to łatwiejszy sposób i nie trzeba dodawać kodu w celu debugowania.

Odys
źródło
2

Umieść punkt przerwania na końcowym nawiasie klamrowym main(). Potknie się nawet przy wielu returninstrukcjach. Jedynym minusem jest to, że wezwanie doexit() nie zostanie złapane.

Jeśli nie debugujesz, postępuj zgodnie ze wskazówkami zawartymi w odpowiedzi Zoidberga i uruchom program za pomocą Ctrl+ F5zamiast po prostu F5.

Czad
źródło
2

Moje 2 centy:

Wybór 1: Dodaj punkt przerwania na końcu main()

Wybór 2: Dodaj ten kod, tuż przed 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');

Musisz uwzględnić <iomanip>dlastd::numeric_limits

Arnav Borborah
źródło
2

po prostu dodaj system („pauza”) na końcu kodu, zanim zwróci 0 w ten sposób

#include <stdlib.h>

int main()
{
    //some code goes here
    system("pause")
    return 0;
}
melpomene
źródło
2
int main()
{
    //...
    getchar();
    return 0;
}
gonnavis
źródło
2

cin.get()Lub system("PAUSE"). Nie słyszałem, że możesz użyćreturn(0);

Udhav Sarvaiya
źródło
1

Dołączam, #include <conio.h>a następnie dodaję getch();tuż przed return 0;wierszem. Tego i tak nauczyłem się w szkole. Metody wymienione powyżej są zupełnie inne, widzę.

Amruth Pillai
źródło
2
-1: Poza tym, że wstrzymanie programu jest zwykle niewłaściwym rozwiązaniem (ponieważ w większości przypadków nie jest to zachowanie, które ma mieć wypuszczony plik binarny), conio.h jest niestandardowy , nieaktualny i jest Nagłówek C, a nie C ++! Niestety w szkołach uczy się wielu złych praktyk programistycznych.
JBentley
Oczekuje się, że zostanie to wykorzystane tylko podczas testowania, nie jest to coś, co chciałbyś zachować w ostatecznej wersji. Jeśli programujesz w systemie Windows, na czym polega problem z #include <conio.h> / _getch () ;? Szybsze pisanie niż cin.get (), nie wymaga naciskania 2 klawiszy (przynajmniej znak + enter) i nie działa tylko w debugowaniu lub tylko w trybie zwolnienia. Co więc jest nie tak?
Barnack
1

Miałem ten sam problem. Używam _getch()tuż przed instrukcją return. To działa.

Jaskółka oknówka
źródło
Możesz dodać przykłady i objaśnienia do swojego kodu, szczególnie w przypadku pytania zadanego / udzielonego tak dawno temu. Ponadto odpowiedź jest funkcjonalnie identyczna z kilkoma starszymi odpowiedziami i wykorzystuje to samo połączenie, co inną istniejącą odpowiedź.
Clockwork-Muse
0

(Niektóre opcje mogą być wywoływane różnymi nazwami. Nie używam wersji angielskiej)

Miałem ten sam problem, kiedy tworzyłem projekty z opcją „pusty projekt”, Utwórz projekt jako „Aplikacja konsoli Win32” zamiast „pusty projekt”. W wyświetlonym oknie dialogowym naciśniesz „kontynuuj”, a następnie możesz zaznaczyć opcję „pusty projekt” i nacisnąć przycisk potwierdzenia. Następnie CTRL + F5 otworzy konsolę, która nie zamyka się automatycznie.

Blechdose
źródło
0

Miałem ten sam problem; W mojej aplikacji jest wiele punktów wyjścia () i nie było sposobu, aby wiedzieć, gdzie dokładnie wychodzi, wtedy dowiedziałem się o tym:

atexit(system("pause"));

lub

atexit(cin.get());

W ten sposób przestanie działać bez względu na to, gdzie wyjdziemy z programu.

Charaf Errachidi
źródło
Żadne z tych połączeń nie jest prawidłowe atexit. atexitprzyjmuje wskaźnik funkcji, a nie liczbę całkowitą.
melpomene
0

Inna opcja:

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

Głównie:

int main(int argc, char* argv[]) {
    MAINRET;
}
chen_767
źródło
0

W rzeczywistości prawdziwym rozwiązaniem jest wybór samego szablonu projektu. MUSISZ wybrać aplikację konsoli Win32 w starszym VS lub wypełnić najpierw nazwę projektu, a następnie dwukrotnie kliknąć kreatora pulpitu systemu Windows, a następnie wybrać aplikację konsoli Win32. Następnie wybierz pusty projekt w tym momencie. Pozwala to na to, czego naprawdę chciał pierwotny pytający bez dodawania dodatkowego punktu zatrzymania i kodu wstrzymania. Przeszedłem również przez ten problem. Odpowiedź znajduje się również na stronie MSDN.

użytkownik9416431
źródło
0

Oto sposób na pozostawienie otwartego okna poleceń bez względu na to, jak wykonanie się zatrzymuje bez modyfikowania kodu:

W Visual Studio otwórz Strony właściwości projektu -> Debugowanie .

W polu Command wpisz$(ComSpec)

W polu Argumenty poleceń wprowadź /k $(TargetPath). Dołącz dowolne argumenty do własnej aplikacji.

Teraz F5 lub Ctrl-F5 wykonuje Windows / System32 / cmd.exe w nowym oknie, a / k zapewnia, że wiersz polecenia pozostanie otwarty po zakończeniu wykonywania.

Minusem jest to, że wykonanie nie kończy się na punktach przerwania.

Jonathan Lidbeck
źródło
0

Jak niektórzy już zauważyli, rozwiązanie Zoidbergs nie dołącza debuggera, czego zwykle nie chcesz.

Najlepszą opcją imo jest odpowiednie skonfigurowanie VS (od VS 2017 r.), Przechodząc do Narzędzia> Opcje> Debugowanie> Ogólne. Tam odznaczasz „Automatycznie zamykaj konsolę po zatrzymaniu debugowania” (na samym dole), co prawdopodobnie jest zaznaczone w twoim przypadku.

iko79
źródło
-1

możesz po prostu umieścić keep_window_open (); przed powrotem tutaj jest jeden przykład

int main()
{
    cout<<"hello world!\n";
    keep_window_open ();
    return 0;
}
Sifis Babionitakis
źródło
2
Skąd się bierze keep_window_open (), np. Który plik nagłówka i biblioteka?
Tom Goodfellow
its from this one std_lib_facilities.h but most of the times you have it included
Sifis Babionitakis