Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > command line argument

Reply
Thread Tools

command line argument

 
 
Owner
Guest
Posts: n/a
 
      04-05-2011
What I'm trying to do with argv is
swapping argv[0] to the end and files argument to the front
reason I'm doing that is in English
cmd options file... is nicely read
do this(cmd) how(option) with file...
but in my language
it's more naturally read
file.... option cmd
so I'm playing around with my codes.

this code below keeps changing argv[0] to file1
can anyone find a fault code below?

Thank you in advance.

void hcmd(int argc, char *argv[])
{
int i, j;
int opcount, agcount;
char **k, **op, **ag;
char *tmp;
char *newarg[100];

k = op = ag = argv;
opcount = agcount = 0;
/* Saving Command */
*k = argv[0];



/* first Option */
if (argc == 1) return;

i = 1;

if (argv[i][0] == '-' || argv[i][0] == '/'){
*op = argv[i++];
opcount++;
}

/* counting rest of options */
for (;i < argc && argv[i][0] == '-' || argv[i][0] == '/';i++)
opcount++;

/* first argument */
if (i < argc){
*ag = argv[i++];
agcount++;
}

/* rest of argument */
for (; i < argc; i++)
agcount++;

for(i=0; i< argc; i++)
printf("%s ", argv[i]);

}
 
Reply With Quote
 
 
 
 
Nobody
Guest
Posts: n/a
 
      04-05-2011
On Mon, 04 Apr 2011 22:52:07 -0400, Owner wrote:

> What I'm trying to do with argv is
> swapping argv[0] to the end and files argument to the front
> reason I'm doing that is in English
> cmd options file... is nicely read
> do this(cmd) how(option) with file...
> but in my language
> it's more naturally read
> file.... option cmd
> so I'm playing around with my codes.
>
> this code below keeps changing argv[0] to file1


Note that argv[0] is typically the name of the program. The first
real *argument* is argv[1].


 
Reply With Quote
 
 
 
 
Peter Nilsson
Guest
Posts: n/a
 
      04-05-2011
Owner <Ow...@Owner-PC.com> wrote:
> What I'm trying to do with argv is
> swapping argv[0] to the end and files argument to the front


A strictly conforming program cannot modify the contents of argv[].

> reason I'm doing that is in English
> cmd options file... is nicely read
> do this(cmd) how(option) with file...
> but in my language
> it's more naturally read
> file.... option cmd
> so I'm playing around with my codes.
>
> this code below keeps changing argv[0] to file1
> can anyone find a fault code below?


argv[0] is the name of the program (in most cases.)

If you just want to print the command line, with argv[0] last,
do something like...

int n;
for (n = 1; n < argc; n++) printf("%s ", argv[n]);
if (argc) puts(argv[0]);

There's no obvious reason to manipulate argv[] just to special
case argv[0].

--
Peter
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      04-05-2011
Owner <> writes:

> What I'm trying to do with argv is
> swapping argv[0] to the end and files argument to the front
> reason I'm doing that is in English
> cmd options file... is nicely read
> do this(cmd) how(option) with file...
> but in my language
> it's more naturally read
> file.... option cmd
> so I'm playing around with my codes.
>
> this code below keeps changing argv[0] to file1
> can anyone find a fault code below?
>
> Thank you in advance.
>
> void hcmd(int argc, char *argv[])
> {
> int i, j;
> int opcount, agcount;
> char **k, **op, **ag;
> char *tmp;
> char *newarg[100];
>
> k = op = ag = argv;


The code makes not assignments to argv so any changes to it occur
through one of these three aliases.

> opcount = agcount = 0;
> /* Saving Command */
> *k = argv[0];


This has no effect so you might as well get rid of k althrogether (along
with j, tmp and newarg that are never even used).

>
>
>
> /* first Option */
> if (argc == 1) return;


argc can be < 1. However, I don't see why you want to do nothing when
argc == 1. I thought you would want to print argv[0] at least.

> i = 1;
>
> if (argv[i][0] == '-' || argv[i][0] == '/'){
> *op = argv[i++];
> opcount++;
> }


This set argv[0] (op is equal to argv so *op is an alias for
*argv).

> /* counting rest of options */
> for (;i < argc && argv[i][0] == '-' || argv[i][0] == '/';i++)


Turn up your compiler warning level! This means

(i < argv && argv[i][0] == '-')
||
(argv[i][0] == '/')

and so this loop can run too far.

> opcount++;
>
> /* first argument */
> if (i < argc){
> *ag = argv[i++];


and here you set argv[0] because ag is equal to argv.

> agcount++;
> }
>
> /* rest of argument */
> for (; i < argc; i++)
> agcount++;
>
> for(i=0; i< argc; i++)
> printf("%s ", argv[i]);
>
> }


If all you want to do is print argv in a different order, then there is
not need to go to all this effort:

void hcmd(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++)
if (argv[i][0] == '-' || argv[i][0] == '/')
printf("%s ", argv[i]);
for (i = 1; i < argc; i++)
if (argv[i][0] != '-' && argv[i][0] != '/')
printf("%s ", argv[i]);
if (argc > 0)
printf("%s", argv[0]);
}

--
Ben.
 
Reply With Quote
 
Francois Grieu
Guest
Posts: n/a
 
      04-05-2011
On 05/04/2011 08:06, Peter Nilsson wrote:
> A strictly conforming program cannot modify the contents of argv[].


Why ? 5.1.2.2.1p2 says
" — The parameters argc and argv and the strings pointed to by the
argv array shall be modifiable by the program, and retain their
last-stored values between program startup and program termination."

Francois Grieu
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      04-05-2011
Francois Grieu <> writes:

> On 05/04/2011 08:06, Peter Nilsson wrote:
>> A strictly conforming program cannot modify the contents of argv[].

>
> Why ? 5.1.2.2.1p2 says
> " — The parameters argc and argv and the strings pointed to by the
> argv array shall be modifiable by the program, and retain their
> last-stored values between program startup and program termination."


That does not include the elements of the array whose first element is
pointed to by argv.

I once suggested that this permission (that the argv pointers themselves
can not be modified) is not very useful and that it may be an oversight.
I was assured that there are cases where it makes sense though it still
seems a little odd to me.

It is, however, certainly clear that the wording you quote does not
permit modification of argv[0] through to argv[argc] in a portable
program.

--
Ben.
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      04-05-2011
On 2011-04-05, Francois Grieu <> wrote:
> On 05/04/2011 08:06, Peter Nilsson wrote:
>> A strictly conforming program cannot modify the contents of argv[].


> Why ? 5.1.2.2.1p2 says
> " ? The parameters argc and argv and the strings pointed to by the
> argv array shall be modifiable by the program, and retain their
> last-stored values between program startup and program termination."


To be picky:

That is two of the three. The contents of argv is the third.

We are assured that argc and argv themselves are modifiable. The members
of the argv array are not mentioned. The strings *pointed to* by the argv
array are mentioned. So imagine the following setup:

char writeable[] = "foo\0";
const char *first = &writeable[0];
char **argv = { (char *) first, NULL };

main(1, argv);

This complies with the description given in the standard, but if you
try to change argv[0], you invoke undefined behavior.

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Owner
Guest
Posts: n/a
 
      04-05-2011
After playing around with code, I got some productive result

the following code changes
for example
"program /1 /2 arg1 arg2 arg3" to
"arg1 arg2 arg3 /1 /2 program"

but here is the catch
if I take out the prinf("\n"); statement in main()
, it does not work
and I still don't know why.
wonder if this is one of the undefined behavior

can anyone guess?

#include <stdio.h>

char **hcmd(int argc, char **argv)
{
#define MAXSTR 100
int i;
int opcount, agcount;
int k, op, ag;

char *newarg[MAXSTR];

opcount = agcount = 0;
i = 0;
/* Saving Command */
k = i++;

/* first Option */
if (argc < i) return;

if (argv[i][0] == '-' || argv[i][0] == '/'){
op = i++;
opcount++;
}

/* counting rest of options */
for (;i < argc && argv[i][0] == '-' || argv[i][0] == '/';i++)
opcount++;

/* first argument */
if (i < argc){
ag = i++;
agcount++;
}

/* rest of argument */
for (; i < argc; i++)
agcount++;

i = 0;
for (; i < agcount; i++)
newarg[i] = argv[ag++];

for (; i < opcount + agcount; i++)
newarg[i] = argv[op++];

newarg[i] = argv[k];
newarg[++i] = NULL;

return newarg;
}

int main
(int argc, char *argv[])
{
int i;

printf("\n");
argv = hcmd(argc, argv);
for (i = 0; i < argc; i++)
printf("%s ", argv[i]);

}
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      04-05-2011
Owner <> writes:

> After playing around with code, I got some productive result
>
> the following code changes
> for example
> "program /1 /2 arg1 arg2 arg3" to
> "arg1 arg2 arg3 /1 /2 program"
>
> but here is the catch
> if I take out the prinf("\n"); statement in main()
> , it does not work
> and I still don't know why.
> wonder if this is one of the undefined behavior


You have undefined behaviour because the function returns the address of
a local object (one that is about to disappear). As a result, you can't
really rely on anything that happens.

> can anyone guess?
>
> #include <stdio.h>
>
> char **hcmd(int argc, char **argv)
> {
> #define MAXSTR 100
> int i;
> int opcount, agcount;
> int k, op, ag;
>
> char *newarg[MAXSTR];
>
> opcount = agcount = 0;
> i = 0;
> /* Saving Command */
> k = i++;


This is not a clear way of writing this. For one thing it is simpler to
set i = 1, k = 0 but that does not explain what k is for. You might as
well set the command name right now:

newarg[argc - 1] = argv[0];

or you can get rid of k and write the line at the end of the function.

> /* first Option */
> if (argc < i) return;


return what?

> if (argv[i][0] == '-' || argv[i][0] == '/'){
> op = i++;
> opcount++;
> }
>
> /* counting rest of options */
> for (;i < argc && argv[i][0] == '-' || argv[i][0] == '/';i++)
> opcount++;


see previous message.

> /* first argument */
> if (i < argc){
> ag = i++;
> agcount++;
> }
>
> /* rest of argument */
> for (; i < argc; i++)
> agcount++;


This increments agcount exactly argc - i times. You might as well write

agcount += argc - 1;

> i = 0;
> for (; i < agcount; i++)
> newarg[i] = argv[ag++];


You can get here without setting ag. This loop is therefore another
source of undefined behaviour.

> for (; i < opcount + agcount; i++)
> newarg[i] = argv[op++];
>
> newarg[i] = argv[k];


k is always 0. Writing argv[0] is clearer than using a variable you set
right up the top of the function.

> newarg[++i] = NULL;
>
> return newarg;


This won't work. You will either have to allocate used allocated
storage or you can have the caller (main) pass an array into which you
write the re-ordered version of argv (that would be my preference).

> }
>
> int main
> (int argc, char *argv[])
> {
> int i;
>
> printf("\n");
> argv = hcmd(argc, argv);
> for (i = 0; i < argc; i++)
> printf("%s ", argv[i]);
>
> }


--
Ben.
 
Reply With Quote
 
Francois Grieu
Guest
Posts: n/a
 
      04-05-2011
On 05/04/2011 19:30, Seebs wrote :
> On 2011-04-05, Francois Grieu<> wrote:
>> On 05/04/2011 08:06, Peter Nilsson wrote:
>>> A strictly conforming program cannot modify the contents of argv[].

>
>> Why ? 5.1.2.2.1p2 says
>> " The parameters argc and argv and the strings pointed to by the
>> argv array shall be modifiable by the program, and retain their
>> last-stored values between program startup and program termination."

>
> To be picky:
>
> That is two of the three. The contents of argv is the third.
>
> We are assured that argc and argv themselves are modifiable. The members
> of the argv array are not mentioned. The strings *pointed to* by the argv
> array are mentioned. So imagine the following setup:
>
> char writeable[] = "foo\0";
> const char *first =&writeable[0];
> char **argv = { (char *) first, NULL };
>
> main(1, argv);
>
> This complies with the description given in the standard, but if you
> try to change argv[0], you invoke undefined behavior.


No contest: I misread "argv is modifiable" as meaning each element
of array argv[] is modifiable; but that's a figment of my imagination.

That's sad, because a few of my tools write into argv[], e.g. to
allow replacing an argument by a computed value.
I've never met an environment where that cause a visible problem.
I bet it is fairly unusual.

Francois Grieu
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
java -jar ignore the classpath command line argument Thomas Kellerer Java 5 04-13-2005 12:01 PM
Command line argument problems Justin Naidl C++ 2 09-18-2004 04:08 PM
Program cannot recognize asterisk(*) as an argument passed from the command line? Fong Java 3 05-27-2004 01:55 AM
ANNOUNCE: SCons 0.94 adds command-line argument features, fixeskey bugs Steven Knight Python 0 11-07-2003 04:56 PM
reading in command line argument nic977 C Programming 13 09-22-2003 02:50 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57