Parameters in Unicode - what am I doing wrong here?

I'm trying to build a console app with Unicode support. I'm using VS.NET, and Unicode is enabled in the project settings. Param parsing doesn't work right, and I'm trying to isolate the problem by having it parrot my params back to me. If I reduce the main function to this:

1
2
3
4
5
6
int main(int argc, TCHAR* argv[])
{
	wcout << argc << L"\n";
	wcout << argv[0] << L"\n";
	wcout << argv[1] << L"\n";
}


And then I run the program like this:
my_tool.exe iamparam

The output looks like this:
1
2
2


It's doing the first line right, but I want the second and third lines to be my_tool.exe and iamparam.

Also, if I debug and add a watch to either argv[0] or argv[1], the apparent value is some weird Chinese characters.

What am I doing wrong?
Last edited on
I am almost 100% sure that Windows will always pass the program parameters as ANSI strings, and never as UNICODE strings. Why? Not sure, but I would dare say backwards compatibility.
Ok, forget about unicode parameters. I just want to compile with Unicode enabled, and have the ANSI parameters work right. How do I do this?
what happens if you simply use the standard way (even with UNICODE enabled):
1
2
3
4
5
6
int main(int argc, char* argv[])
{
	cout << argc ;
	cout << argv[0] ;
	cout << argv[1] ;
}
Strange but true, even with UNICODE defined, and even with that silly main(int, TCHAR**) nonsense that the Wizard generates, the arguments are ASCII.

Defining UNICODE only switches on calling UNICODE versions of system calls. So if you want UNICODE program args, you need to call GetCommandLine and parse the args yourself.
1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>
#include <iostream>

int main(int argc, char* argv[])
{
	std::cout << argv[0] << std::endl;

	LPCTSTR pCmdLine = GetCommandLine();
	std::wcout << pCmdLine << L"\n";

	return 0;
}
Last edited on
1
2
3
4
5
6
7
int main(int argc, char* argv[])
{
	if(argc > 1 && strcmp(argv[1], "foo") == 0)
	{
		doThis();
	}
}


This worked as expected. So, why does the wizard generate main(int, TCHAR*) if it seems to completely break command line arguments? I don't understand why it would put TCHAR* if only char* works.
Last edited on
I'm guessing it's because theoretically there could be a command line that uses UNICODE instead of ASCII, so when it passes you parameters, they would be in UNICODE.
main(int, TCHAR**) is just plain wrong. The whole #define _UNICODE was an idea borne out of expediency. If M$ had enough time, they'd have done it better.

The problem was, after the OS/2 / NT code split, a whole bunch of features were piled into NT to make it defence compliant. The feature list of NT was impressive, right down to that POSIX interface they promised. And among these promises was Unicode support.

The Unicode support works well; really well in fact. The problem was moving the old Windows 3.1/3.11 and Windows for Workgroups developers from the old WIN16 ASCII platform to the new shiny WIN32 Unicode platform.

What they came up with was this crazy scheme where the API calls have W on the end for Unicode, A on the end for ASCII and a _UNICODE macro that maps one or the other to function names, with the ASCII versions being mapped onto Unicode versions in the interface libraries. This necessitated a whole bunch of common string types and function names that could be mapped too to pass the args over.

Who ever wrote the Visual Studio wizard missed the point and thought it applied to things other than the WIN32 API, it doesn't. It doesn't apply to startup code, or main, or any such thing, just API calls.
Last edited on
Topic archived. No new replies allowed.