Как сохранить окно консоли открытым в Visual C ++?

191

Я начинаю с Visual C ++, и я хотел бы знать, как сохранить окно консоли.

Например, это будет типичное приложение "Hello World":

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

Какую черту я пропускаю?

Рауль Роа
источник
Amruth A. Pillai в вашем коде не отображается «нажмите любую клавишу, чтобы продолжить», спасибо
Вы можете распечатать это сами с помощью простого вызова std :: cout.
Рауль Роа
5
Недостатком всех предложенных решений является то, что ни одно из них не работает с отладкой (здесь происходит сбой Ctrl + F5) и когда приложение неожиданно останавливается (все точки останова или чтения из stdin при основном возврате завершаются сбоем здесь). Я хотел бы видеть окно консоли в IDE, как в Eclipse и других IDE. Они просто продолжают показывать вывод в stdout / stderr после завершения программы.
доктор Sybren
@sybren Принятый ответ работает с CTRL + F5, и зачем вам решение, которое работает с отладкой (F5)? Конечно, весь смысл отладки в том, чтобы .. отладить? В чем преимущество наличия приостановленной консоли после завершения программы в сеансе отладки?
JBentley
2
@JBentley Eclipse и другие интегрированные среды разработки позволяют читать выходные данные вашей программы даже после завершения процесса. Конечно, вы видите дополнительное преимущество, особенно когда пытаетесь найти ошибку? Кроме того, точка останова работает только тогда, когда вы знаете, где заканчивается программа, что может быть трудно определить, когда вывод исчезнет с вашего экрана.
доктор Sybren

Ответы:

389

Начните проект с, Ctrl+F5а не просто F5.

Теперь окно консоли будет оставаться открытым с Press any key to continue . . .сообщением после выхода из программы.

Обратите внимание, что для этого требуется Console (/SUBSYSTEM:CONSOLE)опция компоновщика, которую можно включить следующим образом:

  1. Откройте свой проект и перейдите в Solution Explorer. Если вы следите за мной в K & R, ваше «Решение» будет «привет» с одним проектом под ним, а также «привет» жирным шрифтом.
  2. Щелкните правой кнопкой мыши на «привет» (или как называется ваш проект.)
  3. Выберите «Свойства» из контекстного меню.
  4. Выберите «Свойства конфигурации»> «Линкер»> «Система».
  5. Для свойства «Подсистема» в правой панели щелкните раскрывающийся список в правом столбце.
  6. Выберите «Консоль (/ SUBSYSTEM: CONSOLE)»
  7. Нажмите «Применить», подождите, пока он закончит делать все, что он делает, затем нажмите «ОК». (Если «Применить» выделено серым цветом, выберите другой параметр подсистемы, нажмите «Применить», затем вернитесь и примените параметр консоли. Мой опыт показывает, что само по себе «ОК» не будет работать.)

CTRL-F5 и подсказки подсистемы работают вместе; они не являются отдельными вариантами.

(Предоставлено DJMorreTX от http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 )

Зойдберг
источник
36
Это запускает программу без отладки; Лучше иметь решение, которое работает как в режиме отладки, так и в обычном режиме.
ス ー パ ー フ ァ ミ コ ン
3
Для тех, кто не может заставить это решение работать в проекте makefile, это связано с ошибкой в ​​Visual Studio. Я только что опубликовал ответ с исправлением.
JBentley
1
Могу подтвердить! Было консольное приложение, которое не работало, делало это, и это работало. Вам не нужно менять свой код cin.get(),getchar(), system("pause")или любой другой мусор. Изменение это работает.
Каллат
Ctrl + F5 означает «Начать без отладки». Так что вы не можете использовать это при отладке. Просто добавьте system("pause");в конце вашего кода. Это имеет смысл и прекрасно работает.
Милад
41

Стандартный способ - cin.get()до вашего заявления о возврате.

int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World";
    cin.get();
    return 0;
}
Гордон Уилсон
источник
4
Я знаю, поскольку программа уже использует cout, о котором уже позаботились, но я думаю, что стоит упомянуть, что вам нужно #include <iostream>, а также использовать пространство имен std: std :: cin.get () ,
Брайан
7
Это работает, но Ctrl + F5 намного лучше, особенно при отслеживании глобального разрушения объектов и т. Д.
Ternary
8
-1 за _tmain. Я бы проголосовал за -1 cin.get()вместо того, чтобы ставить точку останова для F5 или использовать Ctrl F5. Но мне разрешили только одно понижение.
ура и hth. - Альф
8
@ Cheers: что не так с _tmain? Это стандартный способ написания приложения для Windows, ориентированного на консольную подсистему. Отклонение от этого стандарта - это то, что было бы плохой практикой. Очевидно, что здесь никто не говорит о переносимом коде; вопрос говорит Visual C ++ и _tmainявляется подписью, которая появляется в примере кода. Пришло время отказаться от этой религии. По умолчанию Windows является «нестандартной», и есть очень веские причины для ее соблюдения .
Коди Грей
8
@CodyGray: Мое отрицательное мнение _tmainзаключается в том, что это совершенно ненужный нестандарт (международный стандарт C ++ требует простого main), а также потому, что он использует макросхему Microsoft T, которая является ненужным усложнением и словоблудием для поддержки Windows 9x. Если вы чувствуете, что отклонение от стандарта является плохой практикой, то вам абсолютно не следует его использовать tmain. Нет никаких веских причин для использования tmain, кроме троллинга или для профессионалов, для отображения своей полной некомпетентности.
ура и hth. - Альф
24

Поместите точку останова на returnлинии.

Вы запускаете его в отладчике, верно?

Сэм Харвелл
источник
15
в большинстве случаев сложнее, поскольку внутри программы может быть несколько точек выхода
volzotan
Программа может не запуститься из-за отсутствия DLL и никогда не достигнет этой точки останова
Michael
18

Другой вариант заключается в использовании

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

Хотя это не очень портативный, потому что он будет работать только на Windows, но он будет автоматически печатать

Нажмите любую клавишу чтобы продолжить...

Маркос Марин
источник
1
system («пауза») Будет поддерживать ваш процессор, его не следует использовать. Используйте cin.get () или эквивалентный.
Krythic
systemобъявлен в <stdlib.h>.
Мельпомена
@ Krythic Я только что попробовал, и он не съел 100% процессора. Мой процессор использовался на уровне 0% - 1% все время. Не могу воспроизвести.
Мельпомена
system («pause») будет вызывать команду «pause» в cmd, которая НЕ использует ЦП все время. По сути это эквивалентно _getche ().
Пол Стелиан,
7

Для проектов makefile принятое решение терпит неудачу из-за ошибки в Visual Studio (которая присутствует по крайней мере до версии 2012 - я еще не тестировал 2013). Эта ошибка подробно описана здесь .

Чтобы консоль приостановилась после завершения программы в проекте makefile, выполните следующие действия (это может отличаться для версий, отличных от 2010 - 2012):

1) Перейдите /SUBSYSTEM:CONSOLEна компоновщик. - РЕДАКТИРОВАТЬ : см. Ниже.

2) Откройте файл вашего проекта (.vcxproj) в текстовом редакторе.

3) Внутри корневого <project>тега вставьте следующее:

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

4) Перезагрузите проект в вашем решении.

5) Запустите программу без отладки (CTRL + F5).

РЕДАКТИРОВАТЬ:

Согласно моему комментарию ниже, установка опции компоновщика на /SUBSYSTEM:CONSOLEсамом деле не имеет значения для проектов makefile (и не обязательно даже возможна, если вы используете компилятор, отличный от MSVC). Все, что имеет значение, это то, что параметр добавляется в файл .vcxproj, как описано в шаге 3 выше.

JBentley
источник
Я никогда не слышал об этом шаге 3 раньше. Вы уверены, что это требуется и работает?
Mooing Duck
@mooingduck Да, и после моих комментариев о вашем ответе я обнаружил, что переход /SUBSYSTEM:CONSOLEк компоновщику на самом деле не имеет значения - шаг 3 - это все, что имеет значение. Помните, что мой ответ относится к проектам makefile - в проекте makefile среда IDE не может узнать, что вы передаете компоновщику (возможно, вы даже не используете компилятор, у которого есть /SUBSYSTEM:CONSOLEопция), и это проект сама, которая отслеживает, является ли она консольной программой. Я отредактирую свой ответ соответственно.
JBentley
1
@mooingduck Я также могу подтвердить, что я сам использую это решение в проекте makefile, с SCons в качестве системы сборки и MSVC и MinGW в качестве компиляторов. Я не знаю другого способа заставить IDE приостановить консоль после завершения в режиме без отладки.
Дж
1
Я боюсь, что нет, мой рабочий процесс был наоборот, вызывая SCons из VS. Сначала я вручную создал свои проекты make-файлов VS, чтобы они передавали переменные конфигурации в мой скрипт SCons (например, 32/64 бит, имя компилятора, выпуск / отладка), который затем обрабатывал остальную логику. В этой настройке не было необходимости когда-либо изменять файлы проекта, поэтому я не использовал функцию автоматической генерации SCons. С тех пор я перешел на Linux, поэтому я больше не использую VS. Поскольку это ошибка VS, возможно, стоит отправить запрос функции в SCons для обработки необходимого дополнительного шага.
JBentley
1
В качестве альтернативы, вы можете просто включить некоторый код Python в свой скрипт SCons, чтобы делать это самостоятельно каждый раз, когда создается файл проекта. Я считаю, что файлы проекта VS соответствуют стандарту XML, поэтому добавить недостающие элементы должно быть довольно просто, и для этого потребуется всего несколько строк кода. Я бы предложил начать здесь (для Python 2.x) или здесь (3.x). Этот ответ также может представлять интерес.
JBentley
4

Вы можете использовать cin.get();или cin.ignore();непосредственно перед оператором return, чтобы избежать закрытия окна консоли.

CMS
источник
4

просто поставьте точку останова на последней фигурной скобке main.

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

это работает для меня, нет необходимости работать без отладки. Он также выполняет деструкторы перед достижением точки останова, поэтому вы можете проверить любые сообщения, напечатанные на этих деструкторах, если они у вас есть.

Хуан Кастано
источник
3

Просто добавьте точку останова к закрывающей скобке вашего _tmainметода. Это более простой способ, плюс вам не нужно добавлять код для отладки.

Odys
источник
2

Поместите точку останова на конечную скобку main(). Он будет отключен даже с несколькими returnутверждениями. Единственным недостатком является то, что вызов exit()не будет пойман.

Если вы не отлаживаете, следуйте советам в ответе Зойдберга и начните свою программу с Ctrl+ F5вместо просто F5.

Чад
источник
2

Мои 2 цента:

Вариант 1: Добавить точку останова в конце main()

Вариант 2: добавьте этот код прямо перед 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');

Вы должны включить <iomanip>дляstd::numeric_limits

Арнав Борбора
источник
2

просто добавьте system ("pause") в конце кода перед возвратом 0, как это

#include <stdlib.h>

int main()
{
    //some code goes here
    system("pause")
    return 0;
}
Мельпомена
источник
2

cin.get()или system("PAUSE"). Я не слышал, что вы можете использоватьreturn(0);

Удхав Сарваия
источник
1

Я включаю #include <conio.h>и затем добавляю getch();прямо перед return 0;строкой. Это то, чему я научился в школе. Методы, упомянутые выше здесь, совсем другие, я вижу.

Амрут Пиллаи
источник
2
-1: Помимо того факта, что пауза в самой программе, как правило, является неправильным решением (поскольку в большинстве случаев это не то поведение, которое требуется для вашего выпущенного двоичного файла), conio.h является нестандартным , устаревшим и является Заголовок C, а не C ++! К сожалению, в школах преподается много плохих практик программирования.
Дж
Можно ожидать, что это будет использоваться только во время тестирования, это не то, что вы бы сохранили в финальной версии. Если вы пишете для Windows, в чем проблема с #include <conio.h> / _getch () ;? Он написан быстрее, чем cin.get (), не требует нажатия 2 клавиш (хотя бы символ + ввод) и не работает только в режиме отладки или только в режиме выпуска. Что тогда не так?
Барнак
1

Была такая же проблема. Я использую как _getch()раз перед возвратом заявления. Оно работает.

Мартин
источник
Возможно, вы захотите добавить примеры и пояснения к своему коду, особенно для вопроса, который задавали / отвечали так давно. Кроме того, ваш ответ функционально идентичен нескольким более старым ответам и использует тот же вызов, что и другой существующий ответ.
Заводная муза
0

(Некоторые варианты могут называться разными именами. Я не использую английскую версию)

У меня была такая же проблема, когда я создавал проекты с опцией «пустой проект», создайте проект как «Win32-консольное приложение» вместо «пустой проект». В появившемся диалоговом окне вы нажимаете «продолжить», после чего вы можете проверить опцию «пустой проект» и нажать «Подтвердить». После этого CTRL + F5 откроет консоль, которая не закрывается автоматически.

Blechdose
источник
0

У меня такая же проблема; В моем приложении есть несколько точек выхода (), и не было никакого способа узнать, где именно оно выходит, тогда я узнал об этом:

atexit(system("pause"));

или

atexit(cin.get());

Таким образом, это остановится независимо от того, где мы выйдем из программы.

Хараф Эррахиди
источник
Ни один из этих звонков не является действительным atexit. atexitпринимает указатель на функцию, а не целое число
Мельпомена
0

Другой вариант:

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

В основном:

int main(int argc, char* argv[]) {
    MAINRET;
}
chen_767
источник
0

Собственно, реальным решением является выбор самого шаблона проекта. Вы ДОЛЖНЫ выбрать консольное приложение Win32 в более старой версии VS или сначала ввести имя проекта, а затем дважды щелкнуть мастер Windows Desktop, а затем выбрать консольное приложение Win32. Затем выберите пустой проект в этой точке. Затем это позволяет получить то, чего действительно хотел исходный вопросник, без добавления дополнительной точки остановки и кода удержания. Я тоже прошел через эту проблему. Ответ также на сайте MSDN.

user9416431
источник
0

Вот способ сохранить командное окно открытым независимо от того, как выполнение останавливается без изменения какого-либо кода:

В Visual Studio откройте Страницы свойств проекта -> Отладка .

Для команды введите$(ComSpec)

Для командных аргументов введите /k $(TargetPath). Добавьте любые аргументы в ваше собственное приложение.

Теперь F5 или Ctrl-F5 запускает Windows / System32 / cmd.exe в новом окне, а / k гарантирует, что командная строка остается открытой после завершения выполнения.

Недостатком является то, что выполнение не остановится на контрольных точках.

Джонатан Лидбек
источник
0

Как уже отмечали некоторые, решение Zoidbergs не подключает отладчик, чего вы обычно не хотите.

Лучший вариант imo - настроить VS соответствующим образом (начиная с VS 2017 года), выбрав Сервис> Параметры> Отладка> Общие. Там вы снимаете флажок «Автоматически закрывать консоль при прекращении отладки» (в самом низу), что, вероятно, проверено в вашем случае.

iko79
источник
-1

Вы можете просто поставить keep_window_open (); перед возвращением вот один пример

int main()
{
    cout<<"hello world!\n";
    keep_window_open ();
    return 0;
}
Сифис Бабионитакис
источник
2
Откуда берется keep_window_open (), например, какой заголовочный файл и библиотека?
Том Гудфеллоу
это из этого std_lib_facilities.h, но в большинстве случаев вы включаете его
Sifis Babionitakis