Як зберегти вікно консолі відкритим у Visual C ++?


191

Я починаю з Visual C ++ і хотів би знати, як зберегти вікно консолі.

Наприклад, це буде типовий додаток "привіт світ":

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

Яку лінію мені не вистачає?


Amruth A. Pillai у вашому коді не відображається "натисніть будь-яку клавішу для продовження" дякую

Ви можете роздрукувати його за допомогою простого std :: cout call.
Рауль Роа

5
Мінусом усіх запропонованих рішень є те, що жодне з них не працює з налагодженням (Ctrl + F5 виходить з ладу), і коли програма несподівано зупиняється (всі точки прориву чи зчитування з stdin при головному поверненні не вдається тут). Мені б хотілося побачити вікно в консолі IDE, як Eclipse та інші IDE. Вони просто продовжують показувати вихід на stdout / stderr після завершення програми.
д-р. Sybren

@sybren Прийнята відповідь працює з CTRL + F5, і чому б ви хотіли рішення, яке працює з налагодженням (F5)? Безумовно, вся суть налагодження полягає в .. налагодженні? Яка користь мати призупинену консоль після закінчення програми під час сеансу налагодження?
JBentley

2
@JBentley Eclipse та інші IDE дозволяють читати результати програми навіть після припинення процесу. Напевно ви бачите додаткову користь, особливо коли намагаєтесь знайти помилку? Крім того, точка розриву працює лише тоді, коли ви знаєте, де програма закінчується, що може бути важко сказати, коли вихід зникає з вашого екрану.
д-р. Sybren

Відповіді:


389

Почніть проект із, Ctrl+F5а не просто F5.

Press any key to continue . . .Після закінчення програми вікно консолі залишатиметься відкритим із повідомленням.

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

  1. Відкрийте свій проект та перейдіть до Провідника рішень. Якщо ви слідуєте разом зі мною в K&R, ваш "Рішення" буде "привіт" з 1 проектом під ним, також "привіт" жирним шрифтом.
  2. Клацніть правою кнопкою миші на привіт (або те, що назва вашого проекту.)
  3. У контекстному меню виберіть "Властивості".
  4. Виберіть Властивості конфігурації> Linker> System.
  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. Але мені дозволено лише одне скорочення.
Ура та хт. - Альф

8
@Cheers: Що не так _tmain? Це стандартний спосіб написання програми для Windows, орієнтованої на підсистему Console. Відхилення від цього стандарту - це була б погана практика. Зрозуміло, тут ніхто не говорить про портативний код; запитання говорить про Visual C ++ і _tmainє підписом, який з’являється у зразковому коді. Настав час відмовитися від цієї релігії. Windows за замовчуванням є "нестандартним", і є дуже вагомі причини дотримання його стандартів.
Коді Грей

8
@CodyGray: Моя підтримка _tmainполягає в тому, що це абсолютно непотрібне нестандартне (для міжнародного стандарту C ++ потрібна звичайна main) і тому, що він використовує макросхему Microsoft T, яка є непотрібним ускладненням та багатослівністю для підтримки Windows 9x. Якщо ви вважаєте, що відхилення від стандарту є поганою практикою, тоді вам абсолютно не слід користуватися tmain. Немає вагомих причин для використання tmain, крім тролінгу або для професіоналів, для виявлення повної некомпетентності.
Ура та хт. - Альф

24

Поставте точку розриву на returnлінію.

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


15
Найчастіше важко, оскільки всередині програми може бути кілька точок виходу
вользотан

Програма може не запуститися через відсутність DLL, і ніколи не потрапить у цю точку розриву
Майкл

18

Інший варіант - використовувати

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

Хоча це не дуже портативно, оскільки він працюватиме лише в Windows, але він автоматично надрукує

Натисніть будь-яку кнопку, щоб продовжити...


1
система ("пауза") Триматиме процесник роботи, його не слід використовувати. Використовуйте cin.get () або аналог.
Критичний

systemоголошено в <stdlib.h>.
Мельпомена

@Krythic Я просто спробував це, і він не їв 100% ЦП. Моє використання процесора становило 0% - 1% весь час. Неможливо відтворити.
Мельпомена

система ("пауза") викличе команду "пауза" в cmd, яка НЕ ​​весь час використовує процесор. Це по суті еквівалентно _getche ().
Пол

7

Для Makefile проектів прийняте рішення виходить з ладу через помилку в Visual Studio (яка присутня принаймні до версії 2012 - я ще не перевірила 2013). Ця помилка докладно тут .

Для того щоб мати консольну паузу після завершення програми в проекті makefile, виконайте наступні дії (це може відрізнятися для версій, відмінних від 2010 - 2012):

1) Перейдіть /SUBSYSTEM:CONSOLEдо лінкера. - EDIT : див. Нижче.

2) Відкрийте файл проекту (.vcxproj) у текстовому редакторі.

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

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

4) Перезавантажте проект у своєму рішенні.

5) Запустіть програму без налагодження (CTRL + F5).

Редагувати:

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


Я ніколи раніше не чув про цей крок 3. Ви впевнені, що це потрібно і працює?
Mooing Duck

@mooingduck Так, і після моїх коментарів до вашої відповіді тут , я виявив, що перехід /SUBSYSTEM:CONSOLEдо лінкера насправді не має значення - крок 3 - це все, що має значення. Майте на увазі, моя відповідь стосується makefile-проектів - у проекті makefile IDE не має змоги дізнатися, що ви передаєте на лінкер (можливо, ви навіть не використовуєте компілятор, який має /SUBSYSTEM:CONSOLEможливість), і це проект сама відслідковує, чи призначена вона консольною програмою чи ні. Я відповідно відредагую свою відповідь.
JBentley

1
@mooingduck Я також можу підтвердити, що я сам використовую це рішення у проекті makefile, із SCons як системою збирання, а MSVC та MinGW як компілятори. Я не знаю іншого способу змусити IDE призупинити консоль після закінчення в режимі не налагодження.
JBentley

1
@chuckleplant Боюся, що ні, мій робочий процес був навпаки, дзвонив SCON від VS. Спочатку я вручну створив свої проекти makefile 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(); уникнути закриття вікна консолі, або безпосередньо перед вашим твердженням про повернення.


4

просто поставте точку розриву на останній фігурний кронштейн основного.

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

це працює для мене, не потрібно бігати без налагодження. Він також виконує деструктори перед тим, як вдарити точку розриву, щоб ви могли перевірити друк будь-яких повідомлень на цих деструкторах, якщо вони є.


3

Просто додайте точку розриву до кінцевої дужки _tmainметоду. Це найпростіший спосіб, плюс вам не потрібно додавати код для налагодження.


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

просто додайте систему ("пауза") в кінці коду, перш ніж повернути 0, як це

#include <stdlib.h>

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



1

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


2
-1: Окрім того, що сама пауза у програмі, як правило, є неправильним рішенням (оскільки в більшості випадків це не поведінка, яку ви хочете мати у звільненому бінарному файлі), conio.h є нестандартним , застарілим і є Заголовок C, а не C ++! На жаль, у школі існує багато поганих практик програмування.
JBentley

Очікується, що це буде використано лише під час тестування, це не те, що ви збережете у остаточній версії. Якщо ви кодуєте для Windows, у чому проблема з #include <conio.h> / _getch () ;? Писати швидше, ніж cin.get (), не потрібно натискати 2 клавіші (принаймні символ + Enter) і не працює тільки в налагодженні або лише в режимі випуску. Що тоді не так?
Барнак

1

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


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

0

(Деякі варіанти можуть називатися різними іменами. Я не використовую англійську версію)

У мене була така ж проблема, коли я створював проекти з опцією "порожній проект", Створити проект як "Win32-консольний додаток" замість "порожній проект". У діалоговому вікні, яке з'явиться зараз, ви натискаєте "продовжити", після чого ви можете перевірити опцію "порожній проект" і натиснути підтвердження. Після цього CTRL + F5 відкриє консоль, яка не закриється автоматично.


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;
}

0

Власне, справжнім рішенням є вибір самого шаблону проекту. Ви ОБОВ'ЯЗКОВО обрати програму Win32 Console Application у старшій VS, або спочатку заповніть ім'я проекту, а потім двічі клацніть майстер робочого столу Windows, а потім виберіть консольну програму Win32. Потім виберіть порожній проект у цей момент. Потім це дозволяє те, чого справді хотів оригінальний запитувач, не додаючи додаткової точки зупинки та коду утримування. Я також пройшов цю проблему. Відповідь також на сайті MSDN.


0

Ось спосіб зберегти вікно команди відкритим, незалежно від того, як зупиняється виконання, не змінюючи жодного коду:

У Visual Studio відкрийте Сторінки властивостей проекту -> Налагодження .

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

Для аргументів команд введіть /k $(TargetPath). Додайте будь-які аргументи до власної програми.

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

Мінус у тому, що виконання не зупиняється на точках прориву.


0

Як уже зазначали деякі, рішення Zoidbergs не приєднує налагоджувач, що зазвичай не хочеться.

Найкращий варіант imo - це відповідно налаштувати свій VS (починаючи з VS 2017), перейшовши до Інструменти> Параметри> Налагодження> Загальне. Там ви знімаєте прапорець "Автоматично закривати консоль, коли налагодження припиняється" (в самому низу), що, ймовірно, перевірено у вашому випадку.


-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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.