Solved

Command line arguments

Posted on 2009-05-20
11
526 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
Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

 
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
 

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

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
convert char array to number in c 5 85
IIS Log files on Exchange 2013 server 6 119
Issues with C++ Class 19 92
What is sub-make ? 2 61
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

803 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