How do I format a string for OutputDebugString??

I am using:

OutputDebugString(_T("Some text blah blah\r\n"));

Open in new window


in my VS2010 C++ dll project to writ to the output window.

How do I format a string for this so I can output debug  integer values in my program etc
Wanting2LearnManAsked:
Who is Participating?
 
AndyAinscowFreelance programmer / ConsultantCommented:
#include <stdio.h>

int main( void )
{
   char  buffer[200], s[] = "computer", c = 'l';
   int   i = 35, j;
   float fp = 1.7320534f;

   // Format and print various data:
   j  = sprintf( buffer,     "   String:    %s\n", s ); // C4996
   j += sprintf( buffer + j, "   Character: %c\n", c ); // C4996
   j += sprintf( buffer + j, "   Integer:   %d\n", i ); // C4996
   j += sprintf( buffer + j, "   Real:      %f\n", fp );// C4996
   // Note: sprintf is deprecated; consider using sprintf_s instead

   printf( "Output:\n%s\ncharacter count = %d\n", buffer, j );
}
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
sprintf (and other similar functions) can be found in the help files along with flags they take for providing formatted strings.
0
 
Anthony2000Commented:
If you are using MFC, you can also use CString.


CString s;
int myInt = 34;

s.Format(_T("integer: %d\n"), myInt);
OutputDebugString((LPCTSTR)s);

Open in new window

0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

 
jkrCommented:
I've got my own littly hand-rolled utility for that:
void
LogMessage ( char* pszFormat, ...) {

    static char s_acBuf [ 2048]; // this here is a caveat!

    va_list args;

    va_start ( args, pszFormat);

    vsprintf ( s_acBuf, pszFormat, args);

    OutputDebugString ( s_acBuf);

    va_end ( _args);
}

// example:

LogMessage("Runtime reported exception 0x%lx = %ld, additional info:%d\n", ulCode, ulCode, GetLastError());

Open in new window

0
 
AxterCommented:
Consider using a wrapper function like the following:
 
void trace(const char* format, ...)
{
   char buffer[1000];

   va_list argptr;
   va_start(argptr, format);
   wvsprintf(buffer, format, argptr);
   va_end(argptr);

   OutputDebugString(buffer);
}

Open in new window

0
 
AxterCommented:
I should have refresh the screen before posting.
jkr beat me to it!
0
 
sarabandeCommented:
i once had a project with a solution of your question using c macros and string streams like

#ifdef UNICODE
#define tstring std::wstring
#define tostringstream std::wostringstream
#else
#define tstring std::string                      
#define tostringstream std::ostringstream
#endif

#define FMTDBGSTR(stream)  ((tostringstream&)(tostringstream() << tstring() << stream)).str().c_str() 

Open in new window


that would allow to using dynamic c++ streaming and get a TCHAR* output string, for example like

OutputDebugString(FMTDBGSTR("abc" << 123 << "xyz" << std::endl));

Open in new window


note, i know that c macros is not c++ like. but nevertheless i prefer this before using sprintf.

Sara
0
 
AxterCommented:
FYI:
I would recommend changing the input argument to a constant.
void LogMessage (const char* pszFormat, ...)
0
 
cupCommented:
Have a look in crtdbg.h.  There are routines called _RPTn _RPTWn, _RPTFn, _RPTFWn where n is 0..5

To print 2 values you could do something like

_RPT2(_CRT_WARN, "1st = %s 2nd = %16.6lf\n", astring, adouble);

The W versions are for wide strings
The F versions print the file and line number.

Not as good as the vsprintf technique but you don't have the 2048 size caveat.
0
 
peprCommented:
My +1 to sarabande.  Have a look at Bruce Eckel's "Thinking in C++, 2nd ed Volume 2 (you can download it from http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html), search for the title "Output stream formatting" and the "An exhaustive example" below, the example identified as "//: C04:Format.cpp".  You can get some inspiration.  The fragment:

...
#define D(A) T << #A << endl; A

int main() {
  ofstream T("format.out");
  assure(T);
  D(int i = 47;)
  D(float f = 2300114.414159;)

  const char* s = "Is there any more?";

  D(T.setf(ios::unitbuf);)
  D(T.setf(ios::showbase);)
  D(T.setf(ios::uppercase | ios::showpos);)
  D(T << i << endl;) // Default is dec
  D(T.setf(ios::hex, ios::basefield);)
  D(T << i << endl;)
...

Open in new window


You can even think about the local redefinition of your OutputDebugString().
0
 
peprCommented:
... to add, Bruce Eckel wrote:

This example uses a trick to create a trace file so that you can monitor what’s happening. The macro D(a) uses the preprocessor “stringizing” to turn a into a string to display. Then it reiterates a so the statement is executed. The macro sends all the information to a file called T, which is the trace file. The output is:

int i = 47;
float f = 2300114.414159;
T.setf(ios::unitbuf);
T.setf(ios::showbase);
T.setf(ios::uppercase | ios::showpos);
T << i << endl;
+47
T.setf(ios::hex, ios::basefield);
T << i << endl;
0X2F
...

Open in new window

0
 
Wanting2LearnManAuthor Commented:
re: static char s_acBuf [ 2048]; // this here is a caveat!
 //blah
    OutputDebugString ( s_acBuf);

This gives me the error:
argument of type char* is incompatible with parameter of type "LPCWSTR".

How can I solve this??
0
 
sarabandeCommented:
you seem to have unicode enabled. then the buf should be wchar_t (or TCHAR) rather than char.

static wchar_t s_acBuf [ 2048];

Sara
0
 
peprCommented:
You can define your own overloaded function OutputDebugString() that takes the char* argument (or better const std::string & argument) that makes the output in the desired form (say hex values or a string with escaped control characters, or so).
0
 
sarabandeCommented:
OutputDebugStringA would take a char buffer.

Sara
0
 
Wanting2LearnManAuthor Commented:
re:  then the buf should be wchar_t (or TCHAR) rather than char

error C2664: 'vsprintf' : cannot convert parameter 1 from 'wchar_t[2048]' to 'char *'      

Same error if I use TCHAR.

Any ideas how to solve this???

many Thanks
0
 
sarabandeCommented:
there is function swprintf which takes wide chars.

but i am not sure that you should go the wchar_t way for debugging. use the OutputDebugStringA and it takes single chars.

Sara
0
 
Wanting2LearnManAuthor Commented:
re: but i am not sure that you should go the wchar_t way for debugging

Why do you say this???
0
 
sarabandeCommented:
the UNICODE/ANSI switch in WINAPI normally is for support of languages. i would assume that for debugging purposes you rarely have to print unicode strings. but when using runtime functions you also would have to take the wide char variant and always have to convert char* to wchar_t* what is annoying.

Sara
0
 
sarabandeCommented:
note, the macro solution i posted already has a valid t-switch. so you could use it without bother for wide or narrow char.

Sara
0
 
Anthony2000Commented:
try this modified version of jkr's sample code:
void
LogMessage ( const TCHAR * pszFormat, ...) {

    static TCHAR s_acBuf[2048]; // this here is a caveat!
	int nOutputLength;

    va_list _args;
    va_start(_args, pszFormat);

    outputLength = _vsntprintf_s(s_acBuf, 
	                       sizeof(s_acBuf), 					    _TRUNCATE,					              pszFormat, _args);
    
    if(outputLength >= (sizeof(s_acBuf)/sizeof(TCHAR)))
       OutputDebugString(_T("max buffer may have been exceeded!!\n"));
    OutputDebugString(s_acBuf);

    va_end(_args);
}

Open in new window

0
 
Anthony2000Commented:
I posted the wrong version, here is what I meant to post:
void
LogMessage ( const TCHAR * pszFormat, ...) {

    static TCHAR s_acBuf[2048]; // this here is a caveat!
	int nOutputLength;

    va_list _args;
    va_start(_args, pszFormat);

    nOutputLength = _vsntprintf(s_acBuf, 
                             sizeof(s_acBuf), 						pszFormat, _args);
    if(nOutputLength < 0)
      OutputDebugString(_T("log messsage buffer was not long enough!\n"));
    OutputDebugString(s_acBuf);

    va_end(_args);
}

example of use:

int a,b,c;

a = 43;
b = 44;
c = 55;

LogMessage(_T("the numbers are %d, %d, %d\n"), a, b , c);

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.