我有一个win32项目,我已经加载到Visual Studio 2005中。我希望能够将内容打印到Visual Studio输出窗口,但我不能为我的生活找出方法。我试过'printf'和'cout<<'但是我的信息一直没有印刷。
是否有某种特殊的方式可以打印到Visual Studio输出窗口?
答案 0 :(得分:123)
您可以使用OutputDebugString
。 OutputDebugString
是一个宏,根据您的构建选项映射到OutputDebugStringA(char const*)
或OutputDebugStringW(wchar_t const*)
。在后一种情况下,您必须为该函数提供宽字符串。要创建宽字符文字,您可以使用L
前缀:
OutputDebugStringW(L"My output string.");
通常,您将使用宏版本和_T
宏,如下所示:
OutputDebugString(_T("My output string."));
如果您的项目配置为为UNICODE构建,它将扩展为:
OutputDebugStringW(L"My output string.");
如果您不是为UNICODE构建,它将扩展为:
OutputDebugStringA("My output string.");
答案 1 :(得分:27)
如果项目是GUI项目,则不会显示任何控制台。要将项目更改为控制台,您需要转到项目属性面板并设置:
只有拥有经典的“ int main()”入口点时,此解决方案才有效。
但如果你喜欢我的情况(一个openGL项目),你不需要编辑属性,因为这样做效果更好:
AllocConsole();
freopen("CONIN$", "r",stdin);
freopen("CONOUT$", "w",stdout);
freopen("CONOUT$", "w",stderr);
printf和cout将照常工作。
如果您在创建窗口之前调用AllocConsole,控制台将显示在窗口后面,如果您之后调用它,它将显示在前面。
答案 2 :(得分:12)
要打印到real
控制台,您需要使用链接器标志/SUBSYSTEM:CONSOLE
使其可见。额外的控制台窗口很烦人,但出于调试目的,它非常有价值。
OutputDebugString
将打印到调试器输出。
答案 3 :(得分:4)
如果您需要查看广泛使用printf的现有程序的输出,无需更改代码(或进行最少的更改),您可以按如下方式重新定义printf并将其添加到公共标题(stdafx.h)。
int print_log(const char* format, ...)
{
static char s_printf_buf[1024];
va_list args;
va_start(args, format);
_vsnprintf(s_printf_buf, sizeof(s_printf_buf), format, args);
va_end(args);
OutputDebugStringA(s_printf_buf);
return 0;
}
#define printf(format, ...) \
print_log(format, __VA_ARGS__)
答案 4 :(得分:3)
考虑使用VC ++运行时宏进行报告_RPTN() and _RPTFN()
您可以使用CRTDBG.H中定义的_RPTn和_RPTFn宏来 替换使用printf语句进行调试。这些宏 当_DEBUG没有时,会自动消失在您的发布版本中 已定义,因此无需将它们括在#ifdefs中。
示例...
if (someVar > MAX_SOMEVAR) {
_RPTF2(_CRT_WARN, "In NameOfThisFunc( ),"
" someVar= %d, otherVar= %d\n", someVar, otherVar );
}
或者您可以直接使用VC ++运行时函数_CrtDbgReport, _CrtDbgReportW。
_CrtDbgReport和_CrtDbgReportW可以将调试报告发送到三个不同的目的地:调试报告文件,调试监视器( Visual Studio调试器)或调试消息窗口。
_CrtDbgReport和_CrtDbgReportW通过将参数[n]参数替换为格式来为调试报告创建用户消息 string,使用printf或wprintf定义的相同规则 功能。然后,这些函数生成调试报告和 根据当前报告确定目的地 为reportType定义的模式和文件。当报告发送到 调试消息窗口,文件名,行号和模块名称 包含在窗口中显示的信息中。
答案 5 :(得分:3)
如果要打印十进制变量:
wchar_t text_buffer[20] = { 0 }; //temporary buffer
swprintf(text_buffer, _countof(text_buffer), L"%d", your.variable); // convert
OutputDebugString(text_buffer); // print
答案 6 :(得分:2)
您的Win32项目可能是一个GUI项目,而不是一个控制台项目。这会导致可执行标头的差异。因此,您的GUI项目将负责打开自己的窗口。不过,这可能是一个控制台窗口。调用AllocConsole()
创建它,并使用Win32控制台函数写入它。
答案 7 :(得分:2)
我一直在寻找一种方法来做到这一点并想出一个简单的解决方案。
我假设您在Visual Studio中启动了默认的Win32项目(Windows应用程序),它提供了一个" WinMain"功能。默认情况下,Visual Studio将入口点设置为" SUBSYSTEM:WINDOWS"。您需要先转到:
进行更改项目 - >属性 - >链接器 - >系统 - >子系统
并选择"控制台(/ SUBSYSTEM:CONSOLE)"从下拉列表中。
现在,程序将无法运行,因为" main"需要函数而不是" WinMain"功能
所以现在你可以添加" main"像往常一样在C ++中运行。在此之后,要启动GUI程序,您可以调用" WinMain"功能来自" main"功能
你的程序的起始部分应该看起来像这样:
#include <iostream>
using namespace std;
// Main function for the console
int main(){
// Calling the wWinMain function to start the GUI program
// Parameters:
// GetModuleHandle(NULL) - To get a handle to the current instance
// NULL - Previous instance is not needed
// NULL - Command line parameters are not needed
// 1 - To show the window normally
wWinMain(GetModuleHandle(NULL), NULL,NULL, 1);
system("pause");
return 0;
}
// Function for entry into GUI program
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
// This will display "Hello World" in the console as soon as the GUI begins.
cout << "Hello World" << endl;
.
.
.
现在,您可以使用函数在GUI程序的任何部分输出到控制台,以进行调试或其他目的。
答案 8 :(得分:1)
您还可以使用 WriteConsole 方法在控制台上打印。
AllocConsole();
LPSTR lpBuff = "Hello Win32 API";
DWORD dwSize = 0;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuff, lstrlen(lpBuff), &dwSize, NULL);
答案 9 :(得分:0)
这适用于 MSVC 下的 C++,甚至适用于通过调试器运行时的 GUI 应用程序。它也从发布版本中完全省略。它甚至使用 C++ 字符串流来实现灵活的输入。
#include <iostream>
#ifdef _MSC_VER
#include "Windows.h"
#endif
#if !defined(NDEBUG) && defined(_MSC_VER)
#define LOG(args) {std::stringstream _ss; _ss << __FILE__ << "@" << __LINE__ << ": " \
<< args << std::endl; OutputDebugString(_ss.str().c_str());}
#else
#define LOG(args)
#endif
像这样使用:
LOG("some message " << someValue);