Solved

Command line arguments

Posted on 2009-05-20
11
561 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
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 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

Want Experts Exchange at your fingertips?

With Experts Exchange’s latest app release, you can now experience our most recent features, updates, and the same community interface while on-the-go. Download our latest app release at the Android or Apple stores today!

Question has a verified solution.

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

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
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 tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

617 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