pbibergal
pbibergal

Reputation: 2921

Printing parameters in win32 console application

Here's my code:

int _tmain(int argc, _TCHAR* argv[])
{   
    for (int i = 1;i<argc;i++) printf("Argument %d:%s\n",i,argv[i]);
    // output = Argument 1:param

    for (int k = 1; k < argc; k++) cout << "Argument " << k << ": " << argv[k];
    // output =  Argument 1: 00BF5878
    return(0);
}

My question is: why do I see different outputs on cout and printf?

Upvotes: 1

Views: 3126

Answers (2)

Thomas Matthews
Thomas Matthews

Reputation: 57698

The difference is that printf takes the contents of the parameters and forces the data to match the format specifier. The content of argv[i] will be treated as a nul terminated string because of the %s format specifier.

The cout in conjunction with the stream insertion operator will output based on the type of the parameter. The compiler will search all the operator<<() methods for cout and choose the one the best matches the parameter.

In your case, the compiler is looking for the method operator<<(TCHAR *) and didn't find an exact match. Instead, the compiler recognized that the parameter was a pointer and chose operator<<(void *) which prints out a pointer.

Try defining operator<<(TCHAR*) and see what happens.

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145279

You see an address in the output from cout because you have built the program with UNICODE or _UNICODE defined. Probably by way of a setting in a Visual Studio project. Then _tmain expands to MIcrosoft's non-standard wmain, and _TCHAR expands to wchar_t.

And cout doesn't know how that a pointer to wchar_t is supposed to point to a null-terminated string of wide characters.

I am not sure why that doesn't happen with printf. Lemme check.


OK I have checked and your printf is not printing "param" as you indicate it does.

Here's the corrected code I checked with:

#include <iostream>
#include <stdio.h>
#include <tchar.h>
using namespace std;

int _tmain( int argc, _TCHAR* argv[] )
{
    for( int i = 0;i < argc; ++i )
    {
        printf("printf Argument %d:%s\n",i,argv[i]);
    }

    for( int i = 0;  i < argc;  ++i )
    {
        cout << "cout Argument " << i << ": " << argv[i] << endl;
    }
}

And here's the result:

[D:\dev\test]
> cl foo.cpp /D _UNICODE
foo.cpp

[D:\dev\test]
> foo param
printf Argument 0:f
printf Argument 1:p
cout Argument 0: 004F9A9C
cout Argument 1: 004F9AA4

[D:\dev\test]
> _

In other words, the apparent conundrum is entirely caused by your inaccurate reporting of results.


Solution: instead of using Microsoft's non-standard wmain, and in particular instead of using the now totally meaningless Windows 9x support macros!, use a standard C++ main.

Upvotes: 1

Related Questions