【问题标题】:How to view printf output in a Win32 application on Visual Studio 2010?如何在 Visual Studio 2010 的 Win32 应用程序中查看 printf 输出?
【发布时间】:2011-03-01 20:15:22
【问题描述】:

如何在Visual Studio 2010Win32 应用程序中查看 printf 输出(使用 WinMain 输入)?

【问题讨论】:

  • 您想从应用程序中打开一个单独的控制台窗口,还是想在应用程序主窗口的控件中显示它?还是将其记录到文件中?
  • 实际上,我希望在 xcode 中有类似控制台窗口的东西,您可以在其中看到控制台输出而无需更改任何代码。显示标准输出的日志也可以。

标签: c windows visual-studio


【解决方案1】:

编辑 2021、Visual Studio 2019

要将调试消息写入输出窗口,请使用来自debugapi.hOutputDebugStringA(包括 windows.h)

test.c

#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdShow, int nCmdShow)
{
    int number = 10;
    char str[256];
    sprintf_s(str, sizeof(str), "It works! - number: %d \n", number);

    OutputDebugStringA(str);

    return 0;
}

在 Visual Studio 2019 上测试,调试 / x64。

或者使用我的插入式header 文件。

【讨论】:

  • 显然 256 仅作为示例,但我喜欢这种方法。绝对是我的想法。
  • 当然,只是一个例子。为方便起见,您可以将其包装在类/函数中。很高兴它有帮助!干杯!
  • wchar_t str[256]; wsprintf(str, L"It works! - number: %d \n", number); OutputDebugString(str);
  • 这可行,但添加临时缓冲区很乏味。我喜欢韩的回答除了显示 UI 之外还显示控制台,那么我可以使用printf
【解决方案2】:

您需要一个控制台窗口。到目前为止,最简单的方法是更改​​链接器选项:项目 + 属性、链接器、系统、子系统 = 控制台。添加一个 main() 方法:

int main() {
    return _tWinMain(GetModuleHandle(NULL), NULL, GetCommandLine(), SW_SHOW);
}

【讨论】:

  • _tWinMain 是主函数,而在 Win32 应用程序中称为 WinMain
  • 在我的例子中是 wWinMain。无论如何,非常感谢您的回答。我对在互联网上能找到的所有其他答案都发疯了。与 UI 分开的控制台是最好的选择。
【解决方案3】:

我知道我过去曾使用 AllocConsole 函数完成此操作,但我也记得它比我预期的要复杂一些。

在 AllocConsole 上的快速 Google 搜索会产生似乎相关的 Windows Developer Journal article。从那里开始,以下内容似乎与我记得的相似,虽然很模糊。

void SetStdOutToNewConsole()
{
    int hConHandle;
    long lStdHandle;
    FILE *fp;

    // Allocate a console for this app
    AllocConsole();

    // Redirect unbuffered STDOUT to the console
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen(hConHandle, "w");
    *stdout = *fp;

    setvbuf(stdout, NULL, _IONBF, 0);
}

【讨论】:

  • 由于某种原因,这不适用于彩色输出
  • 使用_open_osfhandle()需要#include &lt;io.h&gt;,使用_O_TEXT需要#include &lt;fcntl.h&gt;
  • 这适用于当前 Windows 10 上的用户吗?因为它不适合我。绝对在过去工作。
【解决方案4】:

另一种不需要更改现有 printf 并打印到 VS 输出窗口的方式是这样的:

#define printf printf2

int __cdecl printf2(const char *format, ...)
{
    char str[1024];

    va_list argptr;
    va_start(argptr, format);
    int ret = vsnprintf(str, sizeof(str), format, argptr);
    va_end(argptr);

    OutputDebugStringA(str);

    return ret;
}

...

printf("remains %s", "the same");

【讨论】:

  • 你是个天才!
【解决方案5】:

感谢 torak 的回答。这对我帮助很大。

我需要一个更大的回滚缓冲区,所以在查看了API functions 之后添加了一些内容。在此分享,以防对其他人有所帮助:

void SetStdOutToNewConsole()
{
    // allocate a console for this app
    AllocConsole();

    // redirect unbuffered STDOUT to the console
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT);
    FILE *fp = _fdopen( fileDescriptor, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );

    // give the console window a nicer title
    SetConsoleTitle(L"Debug Output");

    // give the console window a bigger buffer size
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if ( GetConsoleScreenBufferInfo(consoleHandle, &csbi) )
    {
        COORD bufferSize;
        bufferSize.X = csbi.dwSize.X;
        bufferSize.Y = 9999;
        SetConsoleScreenBufferSize(consoleHandle, bufferSize);
    }
}

这会将回滚(屏幕缓冲区)高度增加到 9999 行。

在 Windows XP 和 Windows 7 上测试。

【讨论】:

  • 要保存像我这样的剪贴画者的查找,还需要为函数和标志定义包含
【解决方案6】:

Here is a page that will tell you how to do this, including sample code.

您必须使用 AllocConsole() 创建一个控制台窗口,然后将 C 标准文件句柄关联到新控制台窗口的 HANDLE。

【讨论】:

【解决方案7】:

对于 MinGW,使用“_A_SYSTEM”而不是“_O_TEXT”。 所以移植的Quintin Willison答案如下:

#include <io.h>
void SetStdOutToNewConsole()
{
  // allocate a console for this app
  AllocConsole();
  // redirect unbuffered STDOUT to the console
  HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _A_SYSTEM);
  FILE *fp = _fdopen( fileDescriptor, "w" );
  *stdout = *fp;
  setvbuf( stdout, NULL, _IONBF, 0 );
  // give the console window a nicer title
  SetConsoleTitle(L"Debug Output");
  // give the console window a bigger buffer size
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  if ( GetConsoleScreenBufferInfo(consoleHandle, &csbi) )
  {
    COORD bufferSize;
    bufferSize.X = csbi.dwSize.X;
    bufferSize.Y = 9999;
    SetConsoleScreenBufferSize(consoleHandle, bufferSize);
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多