如何在 Visual C++ 中保持控制台窗口打开?
Posted
技术标签:
【中文标题】如何在 Visual C++ 中保持控制台窗口打开?【英文标题】:How to keep the console window open in Visual C++? 【发布时间】:2010-10-02 01:34:41 【问题描述】:我刚开始使用 Visual C++,我想知道如何保留控制台窗口。
例如,这将是一个典型的“hello world”应用程序:
int _tmain(int argc, _TCHAR* argv[])
cout << "Hello World";
return 0;
我错过了什么?
【问题讨论】:
Amruth A. Pillai 您的代码没有显示“按任意键继续”谢谢 您可以通过简单的 std::cout 调用自行打印。 所有提议的解决方案的缺点是它们都不适用于调试(此处 Ctrl+F5 失败)以及应用程序意外停止时(此处所有断点或从标准输入读取主返回均失败)。我希望看到像 Eclipse 和其他 IDE 一样的 IDE 控制台窗口。他们只是在程序终止后继续向 stdout/stderr 显示输出。 @sybren 接受的答案适用于 CTRL+F5,为什么您想要一个适用于调试 (F5) 的解决方案?当然,调试的全部意义在于.. 调试?在调试会话中程序终止后暂停控制台有什么好处? @JBentley Eclipse 和其他 IDE 允许您在进程终止后读取程序的输出。您肯定看到了额外的好处,尤其是在尝试查找错误时?此外,断点仅在您知道程序终止的位置时才有效,这很难判断输出何时从屏幕上消失。 【参考方案1】:使用 Ctrl+F5 启动项目,而不仅仅是 F5。
程序退出后,控制台窗口现在将保持打开状态并显示Press any key to continue . . .
消息。
请注意,这需要 Console (/SUBSYSTEM:CONSOLE)
链接器选项,您可以按如下方式启用:
-
打开您的项目,然后转到解决方案资源管理器。如果您在 K&R 中与我一起关注,您的“解决方案”将是“你好”,其下有 1 个项目,“你好”也是粗体。
右键单击“hello”(或任何您的项目名称。)
从上下文菜单中选择“属性”。
选择配置属性>链接器>系统。
对于右侧窗格中的“子系统”属性,单击右侧列中的下拉框。
选择“控制台 (/SUBSYSTEM:CONSOLE)”
单击“应用”,等待它完成所有操作,然后单击“确定”。 (如果“应用”显示为灰色,请选择其他子系统选项,单击“应用”,然后返回并应用控制台选项。我的经验是“确定”本身不起作用。)
CTRL-F5 和子系统提示一起工作;它们不是单独的选项。
(来自 http://social.msdn.microsoft.com/Forums/en-US/vcprerelease/thread/21073093-516c-49d2-81c7-d960f6dc2ac6 的 DJMorreTX 提供)
【讨论】:
这个运行程序不调试;最好有一个在调试和普通运行模式下都可以工作的解决方案。 对于无法在 makefile 项目中使用此解决方案的任何人,这是由于 Visual Studio 中的错误造成的。我刚刚发布了修复的答案。 可以确认!有一个不起作用的控制台应用程序这样做并且它起作用了。您无需使用cin.get(),getchar(), system("pause")
或任何其他垃圾更改您的代码。改变这个工作。
Ctrl+F5 表示“不调试就开始”。所以调试的时候不能用这个。只需在代码末尾添加system("pause");
。这很有意义并且工作正常。【参考方案2】:
标准方式是在您的退货声明之前cin.get()
。
int _tmain(int argc, _TCHAR* argv[])
cout << "Hello World";
cin.get();
return 0;
【讨论】:
我知道,因为程序已经在使用 cout,所以它已经被处理了,但我认为值得一提的是,您需要 #include_tmain
。我会为cin.get()
投票另一个-1,而不是为F5 放置断点或使用Ctrl F5。但我只被允许投反对票。
@Cheers:_tmain
有什么问题?这是编写针对控制台子系统的 Windows 应用程序的标准方法。偏离该标准是不好的做法。显然,这里没有人谈论可移植代码。问题说 Visual C++ 和 _tmain
是示例代码中出现的签名。是时候放弃这个宗教了。默认情况下,Windows 是“非标准”的,遵循 其 标准是有充分理由的。
@CodyGray:我对_tmain
的反对是因为它完全没有必要非标准(国际C++ 标准需要一个普通的main
),并且因为它使用微软的T
宏方案,对于支持Windows 9x 来说是不必要的复杂和冗长。如果你觉得偏离标准是不好的做法,那么你绝对不应该使用tmain
。使用 tmain
没有充分的理由,除非是为了拖钓,或者对于专业人士来说,显示一个人的完全无能。【参考方案3】:
在return
行放置一个断点。
您是在调试器中运行它,对吧?
【讨论】:
大多数时候很困难,因为程序内可能有多个退出点 程序可能由于缺少 DLL 而无法启动,并且永远不会遇到该断点【参考方案4】:另一种选择是使用
#include <process.h>
system("pause");
虽然这不是很便携,因为它只能在 Windows 上工作,但它会自动打印
按任意键继续...
【讨论】:
system("pause") 将保持您的处理器运行,不应使用它。使用 cin.get() 或等效的。system
在<stdlib.h>
中声明。
@Krythic 我刚试过它并没有吃掉 100% 的 CPU。我的处理器使用率一直为 0% - 1%。无法复制。
system("pause") 会在cmd中调用"pause"命令,不会一直占用CPU。它本质上相当于 _getche()。【参考方案5】:
对于 makefile 项目,由于 Visual Studio 中的错误(至少在 2012 版之前存在 - 我还没有测试 2013),因此接受的解决方案失败。这个bug详细here.
要在 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 步。你确定这是必需的并且有效吗? @mooingduck 是的,在我对your answer here 的cmets 之后,我现在发现将/SUBSYSTEM:CONSOLE
传递给链接器实际上是无关紧要的——步骤3 才是最重要的。请记住,我的回答与 makefile 项目有关 - 在 makefile 项目中,IDE 无法知道您传递给链接器的内容(您甚至可能没有使用具有 /SUBSYSTEM:CONSOLE
选项的编译器),而且它是项目本身,它跟踪它是否是一个控制台程序。我将相应地编辑我的答案。
@mooingduck 我还可以确认我自己在 makefile 项目中使用了这个解决方案,SCons 作为构建系统,MSVC 和 MinGW 作为编译器。我知道没有其他方法可以让 IDE 在以非调试模式终止后暂停控制台。
@chuckleplant 恐怕不行,我的工作流程正好相反,从 VS 调用 SCons。我最初手动创建了我的 VS makefile 项目,以便它们将配置变量传递给我的 SCons 脚本(例如 32/64 位、编译器名称、发布/调试),然后处理其余的逻辑。在那个设置中,项目文件不需要改变,所以我没有使用 SCons 的任何自动生成功能。我已经切换到 Linux,所以我不再使用 VS。由于这是一个 VS 错误,因此可能值得向 SCons 提交功能请求以处理所需的额外步骤。
或者,您可以在 SCons 脚本中包含一些 Python 代码,以便在每次生成项目文件时自行完成。我相信 VS 项目文件符合 XML 标准,因此添加缺少的元素应该相当容易,并且只需要几行代码。我建议从here(对于 Python 2.x)或here(3.x)开始。 This answer 也可能感兴趣。【参考方案6】:
您可以在 return 语句之前使用 cin.get();
或 cin.ignore();
以避免关闭控制台窗口。
【讨论】:
【参考方案7】:只需在 main 的最后一个大括号上放一个断点。
int main ()
//...your code...
return 0;
//<- breakpoint here
它对我有用,无需调试即可运行。它还在断点之前执行析构函数,因此您可以检查这些析构函数上打印的任何消息(如果有)。
【讨论】:
【参考方案8】:只需在 _tmain
方法的右括号中添加一个断点。这是一种更简单的方法,而且您无需添加代码即可进行调试。
【讨论】:
【参考方案9】:int main()
//...
getchar();
return 0;
【讨论】:
【参考方案10】:在main()
的结尾大括号上放置一个断点。即使有多个return
语句,它也会被触发。唯一的缺点是不会捕获对exit()
的调用。
如果您不进行调试,请按照 Zoidberg 的回答中的建议并使用 Ctrl+F5 而不仅仅是 F5 来启动您的程序。
【讨论】:
【参考方案11】:我的 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');
您需要为std::numeric_limits
添加<iomanip>
【讨论】:
【参考方案12】:只需在代码末尾添加 system("pause") ,然后像这样返回 0
#include <stdlib.h>
int main()
//some code goes here
system("pause")
return 0;
【讨论】:
【参考方案13】:cin.get()
,或system("PAUSE")
。
没听说你可以用return(0);
【讨论】:
【参考方案14】:正如一些人已经指出的那样,Zoidbergs 解决方案不附加调试器,这是您通常不想要的。
imo 的最佳选择是相应地配置您的 VS(从 VS 2017 开始),方法是转到工具 > 选项 > 调试 > 常规。在那里你取消选中“调试停止时自动关闭控制台”(在最底部),这可能在你的情况下被选中。
【讨论】:
这是正确答案但是,您还需要在链接器中添加控制台 (/SUBSYSTEM:CONSOLE) 选项。 我没有选中这个框,但它仍然关闭。我不知道去哪里将@Wheezil 的建议添加到链接器中。 项目属性->链接器->所有选项搜索“sub”就可以看到【参考方案15】:我包含#include <conio.h>
,然后在return 0;
行之前添加getch();
。反正我在学校就是这么学的。我看到上面提到的方法有很大的不同。
【讨论】:
-1:除了让程序本身暂停通常是错误的解决方案之外(因为在大多数情况下,这不是您希望发布的二进制文件具有的行为),conio.h 是 @ 987654321@,过时了,是 C 头文件,不是 C++!不幸的是,学校里有很多不好的编程实践。 人们希望这仅在测试期间使用,它不是您在最终版本中保留的东西。如果您正在为 Windows 编写代码,#include遇到了同样的问题。我在 return 语句之前使用_getch()
。它有效。
【讨论】:
您可能希望在代码中添加示例和解释,尤其是对于很久以前提出/回答的问题。此外,您的答案在功能上与几个旧答案相同,并且使用与另一个现有答案相同的调用。【参考方案17】:(有些选项可能叫不同的名字。我不使用英文版)
我遇到了同样的问题,当我使用“空项目”选项创建项目时,将项目创建为“Win32-console application”而不是“空项目”。在现在弹出的对话框中,您按“继续”,然后您可以选中“空项目”选项并按确认。之后 CTRL + F5 将打开一个不会自动关闭的控制台。
【讨论】:
【参考方案18】:我遇到了同样的问题;在我的应用程序中有多个 exit() 点,无法知道它到底在哪里退出,然后我发现了这一点:
atexit(system("pause"));
或
atexit(cin.get());
这样,无论我们退出程序的哪个位置,它都会停止。
【讨论】:
这些都不是对atexit
的有效调用。 atexit
采用函数指针,而不是整数。【参考方案19】:
另一种选择:
#ifdef _WIN32
#define MAINRET system("pause");return 0
#else
#define MAINRET return 0
#endif
主要:
int main(int argc, char* argv[])
MAINRET;
【讨论】:
【参考方案20】:其实,真正的解决方案是项目模板本身的选择。 您必须在旧版 VS 中选择 Win32 控制台应用程序,或者先填写项目名称,然后双击 Windows 桌面向导,然后选择 Win32 控制台应用程序。然后此时选择空项目。然后,这允许原始提问者真正想要的东西,而无需添加额外的停止点和保持代码。 我也遇到了这个问题。答案也在 MSDN 网站上。
【讨论】:
【参考方案21】:下面是一种在不修改任何代码的情况下保持命令窗口打开的方法,无论执行如何停止:
在 Visual Studio 中,打开 Project Property Pages -> Debugging。
对于命令,输入$(ComSpec)
对于命令参数,输入/k $(TargetPath)
。将任何参数附加到您自己的应用程序。
现在F5或Ctrl-F5在新窗口中执行Windows/System32/cmd.exe,/k 确保命令提示符在执行完成后保持打开状态。
缺点是执行不会在断点处停止。
【讨论】:
【参考方案22】:你可以把 保持窗口打开(); 这里的return之前是一个例子
int main()
cout<<"hello world!\n";
keep_window_open ();
return 0;
【讨论】:
keep_window_open() 来自哪里,例如哪个头文件和库? 它来自这个 std_lib_facilities.h 但大多数时候你都包含它以上是关于如何在 Visual C++ 中保持控制台窗口打开?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Visual Studio C++ 中使用代码关闭控制台窗口