【问题标题】:How to keep the console window open in Visual C++?如何在 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 允许您在进程终止后读取程序的输出。您肯定看到了额外的好处,尤其是在尝试查找错误时?此外,断点仅在您知道程序终止的位置时才有效,这很难判断输出何时从屏幕上消失。

标签: visual-c++ console


【解决方案1】:

使用 Ctrl+F5 启动项目,而不仅仅是 F5。

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

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

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

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 以及使用 std 命名空间: std::cin.get().
  • 这可行,但 Ctrl+F5 更好,尤其是在跟踪全局对象破坏等时。
  • -1 代表_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 在&lt;stdlib.h&gt; 中声明。
  • @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) 在根&lt;project&gt; 标记内,插入以下内容:

<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 添加&lt;iomanip&gt;

            【讨论】:

              【解决方案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 &lt;conio.h&gt;,然后在return 0; 行之前添加getch();。反正我在学校就是这么学的。我看到上面提到的方法有很大的不同。

                  【讨论】:

                  • -1:除了让程序本身暂停通常是错误的解决方案之外(因为在大多数情况下,这不是您希望发布的二进制文件具有的行为),conio.h 是 @ 987654321@,过时了,是 C 头文件,不是 C++!不幸的是,学校里有很多不好的编程实践。
                  • 人们希望这仅在测试期间使用,它不是您在最终版本中保留的东西。如果您正在为 Windows 编写代码,#include / _getch(); 有什么问题?它的编写速度比 cin.get() 快,不需要按 2 个键(至少一个字符+回车),并且仅在调试或发布模式下不起作用。那怎么了?
                  【解决方案16】:

                  遇到了同样的问题。我在 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 但大多数时候你都包含它
                          猜你喜欢
                          • 2010-12-26
                          • 1970-01-01
                          • 2013-06-01
                          • 2014-04-20
                          • 1970-01-01
                          • 2011-07-01
                          • 1970-01-01
                          • 2023-03-05
                          • 1970-01-01
                          相关资源
                          最近更新 更多