Solved

Command line arguments

Posted on 2009-05-20
11
536 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
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
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 viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

821 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