9

I have a program:

int _tmain(int argc, char* argv[])
{
   std::cout << "STARTING" << std::endl;
   std::cout << "Num inputs: " << argc << std::endl;

   for(int i = 0; i < argc; i++)
      std::cout << argv[i] << std::endl;

that I expect to print out all the command line arguments. However, the output is this:

./Test.exe hello world

STARTING Num inputs: 3 . h w

It appears that it's only looking at the first char in each argument and not the entire char* till termination character.

Anyone have any thoughts?

Additional Notes: Creating it through VS2008, and I am essentially copying and pasting an example on the internet that should work. I have run the program in bash, powershell, and cmd.

tshepang
  • 12,111
  • 21
  • 91
  • 136
jbu
  • 15,831
  • 29
  • 82
  • 105
  • 3
    I beleive `_tmain()` expects `tchar` – ruslik Dec 07 '10 at 21:10
  • Does it still happen if you put a `main` function in your program? IE, after you change the name of `_tmain`... – Edward Strange Dec 07 '10 at 21:11
  • Related: [http://stackoverflow.com/questions/895827/what-is-the-difference-between-tmain-and-main-in-c](http://stackoverflow.com/questions/895827/what-is-the-difference-between-tmain-and-main-in-c) – Adri C.S. Sep 02 '13 at 08:35

4 Answers4

17

Your Visual C++ project is set to Unicode, and your main function is called _tmain. This means that Windows invokes your function and passes you Unicode strings, but you're treating them as ANSI strings by using the char* type. Since the second byte of the first Unicode character is null, this appears as an ANSI string with one character.

Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • This is the correct answer. I changed my project settings to multi-byte character set and it works. THANKS! – jbu Dec 07 '10 at 21:11
  • @jbu so might want to set it as the correct answer. A checkbox below the votins buttons. – khachik Dec 07 '10 at 21:13
  • Sigh...that isn't exactly the lesson you should have learned from this but OK. – Edward Strange Dec 07 '10 at 21:13
  • @Noah, what do you mean? he gave me an understanding of how unicode characters are represented at a low level and why my project is incorrectly parsing it. Is there another lesson to be learned here that I'm not getting? – jbu Dec 07 '10 at 21:16
  • 2
    @jbu - if you're going to use _tmain, follow the signature of _tmain. Otherwise stick with the standard program entry point: main. – Edward Strange Dec 07 '10 at 21:17
  • You should use `_tmain` or `wmain` instead of `main`, and you should avoid the legacy MBCS settings. Unicode is the standard setting for some reason. – Philipp Dec 07 '10 at 21:32
5

Most likely it's compiled with UNICODE settings. You should be using wcout instead of cout if UNICODE is defined. And all strings should be put inside _T().

#ifdef UNICODE
#define tout wcout
#else
#define tout cout
#endif 

int _tmain(int argc, TCHAR* argv[])
{
   std::tout << _T("STARTING") << std::endl;
   std::tout << _T("Num inputs: ") << argc << std::endl;

   for(int i = 0; i < argc; i++)
       std::tout << argv[i] << std::endl;
detunized
  • 15,059
  • 3
  • 48
  • 64
  • or, alternatively, assuming that `_UNICODE` is always defined (MBCS builds aren't really necessary any more since Windows 9x died long ago), use `wmain` and `wchar_t` everywhere. – Philipp Dec 07 '10 at 21:35
  • Also note that `wcout` still doesn't work, see http://blogs.msdn.com/b/michkap/archive/2010/10/07/10072032.aspx – Philipp Dec 07 '10 at 21:40
4

First char? That smells like Unicode being interpreted as ANSI. It makes sense. If you use _tmain then you have to use TCHAR.

Dialecticus
  • 16,400
  • 7
  • 43
  • 103
3

Are you compiling your code in Unicode mode?

In silico
  • 51,091
  • 10
  • 150
  • 143
  • This is another correct answer. I changed my project settings to multi-byte character set and it works. THANKS! – jbu Dec 07 '10 at 21:12
  • @jbu: Don't do this, you'll lose Unicode functionality. The MBCS mode is only for backwards compatibility. – Philipp Dec 07 '10 at 21:33