Tôi nên sử dụng chức năng nào để xuất văn bản ra cửa sổ "Đầu ra" trong Visual Studio?
Tôi đã thử printf()
nhưng nó không hiển thị.
Câu trả lời:
Hàm OutputDebugString sẽ làm việc đó.
mã ví dụ
void CClass::Output(const char* szFormat, ...)
{
char szBuff[1024];
va_list arg;
va_start(arg, szFormat);
_vsnprintf(szBuff, sizeof(szBuff), szFormat, arg);
va_end(arg);
OutputDebugString(szBuff);
}
WCHAR szBuff[1024]
_vsnwprintf
Nếu điều này là để gỡ lỗi đầu ra thì OutputDebugString là những gì bạn muốn. Một macro hữu ích:
#define DBOUT( s ) \
{ \
std::ostringstream os_; \
os_ << s; \
OutputDebugString( os_.str().c_str() ); \
}
Điều này cho phép bạn nói những điều như:
DBOUT( "The value of x is " << x );
Bạn có thể mở rộng điều này bằng cách sử dụng __LINE__
và __FILE__
macro để cung cấp thêm thông tin.
Đối với những người trong Windows và vùng đất ký tự rộng:
#include <Windows.h>
#include <iostream>
#include <sstream>
#define DBOUT( s ) \
{ \
std::wostringstream os_; \
os_ << s; \
OutputDebugStringW( os_.str().c_str() ); \
}
Sử dụng OutputDebugString
hàm hoặc TRACE
macro (MFC) cho phép bạn thực hiện printf
định dạng theo kiểu:
int x = 1;
int y = 16;
float z = 32.0;
TRACE( "This is a TRACE statement\n" );
TRACE( "The value of x is %d\n", x );
TRACE( "x = %d and y = %d\n", x, y );
TRACE( "x = %d and y = %x and z = %f\n", x, y, z );
Mẹo hữu ích - nếu bạn sử dụng __FILE__
và __LINE__
sau đó định dạng gỡ lỗi của bạn thành:
"file(line): Your output here"
thì khi bạn nhấp vào dòng đó trong cửa sổ xuất, Visual Studio sẽ chuyển trực tiếp đến dòng mã đó. Một ví dụ:
#include <Windows.h>
#include <iostream>
#include <sstream>
void DBOut(const char *file, const int line, const WCHAR *s)
{
std::wostringstream os_;
os_ << file << "(" << line << "): ";
os_ << s;
OutputDebugStringW(os_.str().c_str());
}
#define DBOUT(s) DBOut(__FILE__, __LINE__, s)
Tôi đã viết một bài đăng trên blog về điều này để tôi luôn biết mình có thể tra cứu nó ở đâu: https://windowscecleaner.blogspot.co.nz/2013/04/debug-output-tricks-for-visual-studio.html
Sử dụng OutputDebugString thay vì afxDump.
Thí dụ:
#define _TRACE_MAXLEN 500
#if _MSC_VER >= 1900
#define _PRINT_DEBUG_STRING(text) OutputDebugString(text)
#else // _MSC_VER >= 1900
#define _PRINT_DEBUG_STRING(text) afxDump << text
#endif // _MSC_VER >= 1900
void MyTrace(LPCTSTR sFormat, ...)
{
TCHAR text[_TRACE_MAXLEN + 1];
memset(text, 0, _TRACE_MAXLEN + 1);
va_list args;
va_start(args, sFormat);
int n = _vsntprintf(text, _TRACE_MAXLEN, sFormat, args);
va_end(args);
_PRINT_DEBUG_STRING(text);
if(n <= 0)
_PRINT_DEBUG_STRING(_T("[...]"));
}
Mặc dù OutputDebugString
thực sự in một chuỗi ký tự vào bảng điều khiển trình gỡ lỗi, nó không hoàn toàn giống như printf
việc sau này có thể định dạng các đối số bằng cách sử dụng %
ký hiệu và một số đối số thay đổi, điều gì đó OutputDebugString
không làm được.
Tôi sẽ đưa ra trường hợp rằng _RPTFN
macro, với _CRT_WARN
đối số ít nhất, là phù hợp hơn trong trường hợp này - nó định dạng chuỗi chính giống như printf
, ghi kết quả vào bảng điều khiển trình gỡ lỗi.
Người chưa thành niên (và kỳ lạ, theo ý kiến của tôi) báo trước với nó là nó đòi hỏi ít nhất một đối số sau chuỗi định dạng (một với tất cả các %
sử dụng quyền thay), một giới hạn printf
nào không bị ảnh hưởng từ.
Đối với các trường hợp bạn cần một puts
chức năng tương tự - không cần định dạng, chỉ cần viết chuỗi như hiện tại - đó là anh chị em của nó _RPTF0
(bỏ qua các đối số theo sau chuỗi định dạng, một cảnh báo kỳ lạ khác). Hoặc OutputDebugString
tất nhiên.
Và nhân tiện, cũng có tất cả mọi thứ từ _RPT1
đến _RPT5
nhưng tôi chưa thử chúng. Thành thật mà nói, tôi không hiểu tại sao cung cấp quá nhiều thủ tục về cơ bản lại làm cùng một thứ.