Solved

Command line arguments

Posted on 2009-05-20
11
516 Views
Last Modified: 2012-05-07
I'm using MS Visual Studio 2005 and creating a Windows console application.  It seems to me the reading of command line arguments is not working correctly.
In the code below, argv[n] only contains the first character of the command line input.

I get the following output:

C:\myproject>test.exe 123 abc
Argument 0:  t
Argument 1:  1
Argument 2:  a

I expected argv to contain
test.exe
123
abc

What am I doing wrong?

Thanks.
// test.cpp : Defines the entry point for the console application.

//
 

#include "stdafx.h"

#include "stdio.h"

#include "string.h"
 
 

int _tmain(int argc, _TCHAR* argv[])

{

	for ( int i=0; i < argc; i++ ){
 

		printf("Argument %i:  %s\n", i, argv[i]);

	}

	return 0;

}

Open in new window

0
Comment
Question by:JohnSantaFe
  • 3
  • 3
  • 3
  • +2
11 Comments
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24434434
Probably because you are using a TCHAR type for argv, I don't think that works.

Try:

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

I will look it up, but I think the standard requires argv to be a standard char **
0
 
LVL 40

Accepted Solution

by:
evilrix earned 500 total points
ID: 24434445
The reason is because the arguments are wide chars so every second byte int he 16 byte TCHAR is a null so it's being cut short.

Try this...

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

Remember to include iostream for this to work.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 24434472
>> Probably because you are using a TCHAR type for argv, I don't think that works.
Sure it does... Microsoft compiles will allow Wide or Narrow for argv, this is the default of how the compiler creates a project. The problem is if it's wide the 2nd bytes are most likely 0

e.g.

'A' == 0x41
L'A' == 0x4100

But %s is expecting a stream of narrow chars so when it hits the 2nd byte in the wide char it sees a null and terminates
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24434496
You are right, I just looked at some UNICODE projects, and I had never even noticed argv was wide character!

0
 
LVL 9

Expert Comment

by:JohnGaby
ID: 24434537
_wprintf is the wide version of printf.  If you use _tprintf then it will map to the wide version if you are using unicode (which is default for 2005), or to the ansi version if you are not using unicode:

http://msdn.microsoft.com/en-us/library/wc7014hz(VS.80).aspx
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:JohnSantaFe
ID: 24434554
Well,

Switching to char* didn't work.

Using _TCHAR*  and wcout worked.

But I don't quite get it.  Seems like this would break a million console applications....?
0
 

Author Comment

by:JohnSantaFe
ID: 24434579
Ah, I see, when using _tmain you get the wide version.

When I used the code below it worked as expected.

Thanks.

#include "stdafx.h"

#include "stdio.h"

#include "string.h"
 
 
 
 
 

int main(int argc, char* argv[])  //note changed from _tmain()

{

	for ( int i=0; i < argc; i++ ){
 

		printf("Argument %i:  %s\n", i, argv[i]);
 

	}

	return 0;

}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 24434594
>> But I don't quite get it.  Seems like this would break a million console applications....?
Wide chars (in Windows) are 2 bytes and narrow are 1. Most of the standard narrow ASCII chars map to wide chars by just setting byte 0 to be the same as the narrow value and byte 1 to 0x00. This is a null char and since C functions user null to signify the end of a string that's why you only see the first char.

When you try and printf L'A' it see 2 chars, 'A' and '\0'
0
 
LVL 2

Expert Comment

by:quickcat88
ID: 24434598
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24434603
>>Ah, I see, when using _tmain you get the wide version.

You and I both, I also did not notice _tmain before responding so I learned something as well.
0
 

Author Closing Comment

by:JohnSantaFe
ID: 31583622
Thanks for the help.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now