如何在Visual C ++中保持控制台窗口打开?


190

我是从Visual C ++开始的,我想知道如何保留控制台窗口。

例如,这将是一个典型的“ hello world”应用程序:

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

我想念的是哪一行?


Amruth A. Pillai您的代码未显示“按任意键继续”,谢谢

您可以通过简单的std :: cout调用自己打印。
劳尔·罗阿2013年

5
所有建议的解决方案的不利之处在于它们都无法与调试一起使用(此处Ctrl + F5失败)以及当应用程序意外停止时(所有断点或在主返回处从stdin读取均失败)。我很想看到一个像Eclipse和其他IDE一样的IDE控制台窗口。在程序终止后,它们只是继续将输出显示到stdout / stderr。
博士 Sybren

@sybren可接受的答案适用于CTRL + F5,为什么要使用调试(F5)的解决方案?当然,调试的全部重点是调试。在调试会话中,在程序终止后暂停控制台会有什么好处?
JBentley

2
@JBentley Eclipse和其他IDE允许您即使在进程终止后仍读取程序的输出。您肯定会看到额外的好处,尤其是在尝试查找错误时?同样,断点仅在您知道程序在何处终止时才起作用,这很难确定输出何时从屏幕上消失。
博士 Sybren 2014年

Answers:


388

使用Ctrl+F5而不是来启动项目F5

Press any key to continue . . .程序退出后,控制台窗口现在将保持打开状态并显示消息。

请注意,这需要Console (/SUBSYSTEM:CONSOLE)链接器选项,您可以按以下方式启用它:

  1. 打开您的项目,然后转到解决方案资源管理器。如果您与我一起在K&R中关注,那么您的“解决方案”将是“ hello”,下面有1个项目,粗体显示“ hello”。
  2. 右键单击“ hello”(或任何项目名称)。
  3. 从上下文菜单中选择“属性”。
  4. 选择“配置属性>链接器>系统”。
  5. 对于右侧窗格中的“子系统”属性,单击右侧列中的下拉框。
  6. 选择“控制台(/ SUBSYSTEM:CONSOLE)”
  7. 单击“应用”,等待其完成所有操作,然后单击“确定”。(如果“应用”变灰,请选择其他子系统选项,单击“应用”,然后返回并应用控制台选项。我的经验是,“确定”本身是行不通的。)

CTRL-F5和子系统提示可以协同工作;它们不是单独的选项。

(由DJMorreTX提供,网址为http://social.msdn.microsoft.com/Forums/zh-CN/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6


36
这将在不调试的情况下运行程序;最好有一个既能在调试模式又能在普通运行模式下工作的解决方案。
スーパーファミコン

3
对于无法获得此解决方案以在Makefile项目中工作的任何人,这是由于Visual Studio中的错误所致。我刚刚发布了解决方案的答案。
JBentley 2014年

1
可以确认!如果有一个无法正常运行的控制台应用程序,那么它可以正常工作。您无需使用cin.get(),getchar(), system("pause")或任何其他垃圾来更改代码。改变这项工作。
卡拉特

Ctrl + F5表示“无需调试即可启动”。因此,调试时不能使用此功能。只需system("pause");在代码末尾添加即可。这很有意义并且可以正常工作。
米拉德

41

标准方法是cin.get()在您的return语句之前。

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

4
我知道,因为该程序已经在使用cout了,所以已经解决了,但是我认为值得一提的是,您将需要#include <iostream>以及使用std名称空间:std :: cin.get() 。
布赖恩2009年

7
这工作,但按Ctrl + F5要好得多尤其是跟踪全球物件破坏等时
三元

8
-1表示_tmain。我会再给-1投票,cin.get()而不是为F5放置断点或使用Ctrl F5。但是我只能选一位。
干杯和健康。-Alf

8
@干杯:怎么了_tmain?这是编写针对控制台子系统的Windows应用程序的标准方法。偏离该标准将是一种不良做法。显然,这里没有人在谈论可移植代码。这个问题说是Visual C ++,_tmain是示例代码中出现的签名。现在该放弃这种宗教了。Windows默认情况下是“非标准的”,并且有充分的理由遵循标准。
科迪·格雷

8
@CodyGray:我的反对意见_tmain是因为它完全是不必要的非标准(国际C ++标准要求使用纯格式main),并且因为它使用了Microsoft的T宏方案,因此不需要复杂和繁琐的语言即可支持Windows 9x。如果您认为偏离标准是不好的做法,那么绝对不要使用tmaintmain除了拖钓,或者对于专业人员而言,没有充分的理由来显示自己的全部能力。
干杯和健康。-Alf 2012年

24

return在行上放置一个断点。

您正在调试器中运行它,对吗?


15
大多数时候
都很

该程序可能由于缺少DLL而无法启动,并且从未遇到该断点
Michael

17

另一种选择是使用

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

尽管这不是很可移植,因为它只能在Windows上运行,但是会自动打印

按任意键继续...


1
system(“ pause”)将保持处理器运行,不应该使用它。使用cin.get()或同等功能。
Krythic

system在中声明<stdlib.h>
melpomene'1

@Krythic我只是尝试了一下,它没有吃掉100%的CPU。我的处理器使用率一直为0%-1%。无法复制。
melpomene'1

system(“ pause”)将在cmd中调用“ pause”命令,该命令不会一直使用CPU。它本质上等效于_getche()。
Paul Stelian

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,则即使可能也不可能)。重要的是,按照上述步骤3,将设置添加到.vcxproj文件。


我之前从未听说过该步骤3。您确定这是必需的并且可行吗?
Mooing Duck

@mooingduck是的,在对您的回答发表评论之后,我现在发现传递/SUBSYSTEM:CONSOLE给链接器实际上是无关紧要的-步骤3至关重要。请记住,我的答案与makefile项目有关-在makefile项目中,IDE无法知道要传递给链接器的内容(您甚至可能没有使用带有/SUBSYSTEM:CONSOLE选项的编译器),而这就是项目本身,它会跟踪它是否打算成为控制台程序。我将相应地编辑我的答案。
JBentley 2014年

1
@mooingduck我也可以确认自己在makefile项目中使用了该解决方案,其中以SCons为构建系统,MSVC和MinGW为编译器。我知道,没有其他方法可以让IDE在非调试模式下终止后暂停控制台。
JBentley

1
@chuckleplant恐怕不是,我的工作流程却相反,从VS调用SCons。最初,我手动创建了VS makefile项目,以便它们将配置变量传递给SCons脚本(例如32/64位,编译器名称,发行版/调试),然后再处理其余的逻辑。在那种设置中,不需要更改项目文件,因此我没有使用SCons的任何自动生成功能。从那以后我就切换到Linux了,所以我不再使用VS。由于这是VS错误,因此可能值得向SCons提交功能请求以处理所需的额外步骤。
JBentley

1
另外,您可以在SCons脚本中包含一些Python代码,以在每次生成项目文件时自行完成。我相信VS项目文件符合XML标准,因此添加缺少的元素应该相当容易,并且只需要几行代码。我建议从此处(对于Python 2.x)或此处(3.x)开始。这个答案可能也很有趣。
JBentley

4

您可以在return语句之前使用cin.get();cin.ignore();,以避免控制台窗口关闭。


4

只需在main的最后一个大括号上放置一个断点即可。

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

它对我有用,无需调试即可运行。它还在达到断点之前执行析构函数,因此您可以检查在这些析构函数上显示的任何消息。


3

只需在方法的右括号中添加一个断点即可_tmain。这是更简单的方法,而且您无需添加代码即可进行调试。


2

在的大括号处放置一个断点main()。即使有多个return语句,它也会跳闸。唯一的缺点是打到的电话exit()不会被捕获。

如果您不是要调试,请按照Zoidberg的建议进行操作,并使用Ctrl+ F5而不是just 启动程序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;
}



1

我包括#include <conio.h>然后在行getch();之前添加return 0;。无论如何,这就是我在学校学到的。我在这里提到的上述方法有很大的不同。


2
-1:除了使程序本身暂停通常是错误的解决方案(因为在大多数情况下,这不是您要释放的二进制文件所具有的行为)之外,conio.h是非标准的,过时的,并且是C标头,而不是C ++!不幸的是,学校里有很多不良的编程习惯。
JBentley 2014年

有人希望只在测试期间使用它,而不是在最终版本中保留的东西。如果您正在为Windows进行编码,则#include <conio.h> / _getch();有什么问题?它比cin.get()更快地编写,不需要按2个键(至少一个字符+输入),并且仅在调试或仅在释放模式下不起作用。那怎么了
巴纳克

1

有同样的问题。我_getch()在return语句之前使用 。有用。


您可能想在代码中添加示例和解释,特别是对于很久以前提出/回答的问题。此外,您的答案在功能上与几个较旧的答案相同,并且使用与另一个现有答案相同的呼叫。
Clockwork-Muse 2014年

0

(某些选项的名称可能不同。我不使用英文版本)

我有同样的问题,当我创建带有选项“空项目”的项目时,将项目创建为“ Win32控制台应用程序”而不是“空项目”。在现在弹出的对话框中,按“继续”,然后您可以选中“空项目”选项并按确认。之后,CTRL + F5将打开不会自动关闭的控制台。


0

我有同样的问题; 在我的应用程序中,有多个exit()点,无法知道确切的退出位置,于是我发现了这一点:

atexit(system("pause"));

要么

atexit(cin.get());

这样,无论我们在程序中的何处退出,它都将停止。


这些都不是对的有效调用atexitatexit需要一个函数指针,而不是整数。
melpomene'1

0

另外的选择:

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

在主要方面:

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

0

实际上,真正的解决方案是选择项目模板本身。您必须在较早的VS中选择Win32控制台应用程序,或先填写项目名称,然后双击Windows桌面向导,然后选择Win32控制台应用程序。然后选择空项目。这样就可以满足原始提问者的真正需求,而无需添加额外的停止点和保持代码。我也遇到了这个问题。答案也在MSDN站点上。


0

这是一种使命令窗口保持打开状态的方法,而不管执行如何停止而无需修改任何代码:

在Visual Studio中,打开“ 项目属性页” ->“ 调试”

对于Command,输入$(ComSpec)

对于命令参数,输入/k $(TargetPath)。将任何参数附加到您自己的应用程序。

现在,F5Ctrl-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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.