The different ways to use argv

G

GWTNewbie

Pleasantries:
It's been a while since I last participated in the newsgroup (over 2 decades under a different handle). A lot has changed, so if I'm out of line in any of my postings, please "prod" me in the right direction.

Question:
I need help interpreting K&R's (2nd Edition) explanation of argv. Specifically, the book puts two constructs into a single program: ++argv[0] and (++argv)[0]. The program itself is supposed to "intelligently" implement program switches. Here's an example:

progname -o -r -s filename.out
progname -o -rs filename.out
progname -sor filename.out

All 3 of these command implementations should produce the same result.

Can someone here provide me a "very detailed" explanation - a diagramatic illustration if possible - of the difference between ++argv[0] and (++argv)[0] and it's used to implement handling program switches to result it the above description?
 
J

Jorgen Grahn

.
The program itself is supposed to
"intelligently" implement program switches. Here's an example:

progname -o -r -s filename.out
progname -o -rs filename.out
progname -sor filename.out

All 3 of these command implementations should produce the same result.

This doesn't answer your question, but on Unix (where these
command-line semantics come from) you should use getopt(3) to do the
parsing for you.

As a user, I'm always frustrated when the commandline syntax of some
tool looks superficially normal, but isn't when you look closer.
Letting argument-less flags combine in any order is a good start, but
there are other features you expect to be present too, e.g. "--" to
end argument processing.

/Jorgen
 
J

John Gordon

In said:
progname -o -r -s filename.out
progname -o -rs filename.out
progname -sor filename.out
Can someone here provide me a "very detailed" explanation - a
diagramatic illustration if possible - of the difference between
++argv[0] and (++argv)[0] and it's used to implement handling program
switches to result it the above description?

argv[0] is the first argument to your program. In your examples above,
it would be "progname".

++argv[0] increments the pointer within the first argument, making it
point to the next successive character, and then yields that value.
Using your examples above, executing this statement three times:

printf("%s\n", ++argv[0]);

Would produce these results:

rogname
ogname
gname

(++argv)[0] advances argv to point to the next argument and then yields
that value. Using your first example above, executing this statement three
times:

printf("%s\n", (++argv)[0]);

Would produce these results:

-o
-r
-s
 
L

Les Cargill

GWTNewbie said:
Pleasantries: It's been a while since I last participated in the
newsgroup (over 2 decades under a different handle). A lot has
changed, so if I'm out of line in any of my postings, please "prod"
me in the right direction.

Question: I need help interpreting K&R's (2nd Edition) explanation of
argv. Specifically, the book puts two constructs into a single
program: ++argv[0] and (++argv)[0]. The program itself is supposed to
"intelligently" implement program switches. Here's an example:

progname -o -r -s filename.out progname -o -rs filename.out progname
-sor filename.out

All 3 of these command implementations should produce the same
result.

Can someone here provide me a "very detailed" explanation - a
diagramatic illustration if possible - of the difference between
++argv[0] and (++argv)[0] and it's used to implement handling program
switches to result it the above description?

++argv[0] says "Increment the first pointer of the argv array."

(++argv)[0] says "increment argv and reference the first thing it
points to." Having argv have an l-value is Bad. Both argv and argc
should be treated as as const as possible...
 
S

Stephen Sprunk

GWTNewbie said:
Can someone here provide me a "very detailed" explanation - a
diagramatic illustration if possible - of the difference between
++argv[0] and (++argv)[0] and it's used to implement handling
program switches to result it the above description?

++argv[0] says "Increment the first pointer of the argv array."

(++argv)[0] says "increment argv and reference the first thing it
points to." Having argv have an l-value is Bad. Both argv and argc
should be treated as as const as possible...

I thought using a loop to "consume" switches by modifying argv/argc,
leaving only the filenames that follow (if any), was the canonical way
of processing command lines.

Of course, nobody should be writing such code at all these days; just
use getopt(3) and be done with it. (But, without having looked, I'd bet
that getopt(3) uses the above algorithm as well.)

S
 
S

Stephen Sprunk

Can someone here provide me a "very detailed" explanation - a
diagramatic illustration if possible - of the difference between
++argv[0] and (++argv)[0] and it's used to implement handling
program switches to result it the above description?

Assume p is a pointer to an array of strings (i.e. pointers to char).
What is the difference between "*(++p)" and "++(*p)" ?

One steps through the array of strings (from one string to the next),
and the other steps through the current string (from one char to the next).

Now apply that understanding to your argv[] question.

For completeness, also study how "*(p++)" and "(*p)++" behave; they're
subtly different from the preincrement forms, and you'll benefit from
being able to use all four forms at the appropriate times.

S
 
G

glen herrmannsfeldt

Stephen Sprunk said:
GWTNewbie said:
Can someone here provide me a "very detailed" explanation - a
diagramatic illustration if possible - of the difference between
++argv[0] and (++argv)[0] and it's used to implement handling
program switches to result it the above description?
(snip)

I thought using a loop to "consume" switches by modifying argv/argc,
leaving only the filenames that follow (if any), was the canonical way
of processing command lines.

With call by value, argc and argv are local copies, so there should
not be any problem modifying them.

It is better not to modify argv for any i, and even more, not modify
*argv, but as I understand it, it is legal for unix. (With some
restrictions that I don't know about.)
Of course, nobody should be writing such code at all these days; just
use getopt(3) and be done with it. (But, without having looked, I'd bet
that getopt(3) uses the above algorithm as well.)

Most of my programs are simple enough that I don't do that.

-- glen
 
L

Les Cargill

Stephen said:
GWTNewbie said:
Can someone here provide me a "very detailed" explanation - a
diagramatic illustration if possible - of the difference between
++argv[0] and (++argv)[0] and it's used to implement handling
program switches to result it the above description?

++argv[0] says "Increment the first pointer of the argv array."

(++argv)[0] says "increment argv and reference the first thing it
points to." Having argv have an l-value is Bad. Both argv and argc
should be treated as as const as possible...

I thought using a loop to "consume" switches by modifying argv/argc,
leaving only the filenames that follow (if any), was the canonical way
of processing command lines.

Yep.

Of course, nobody should be writing such code at all these days; just
use getopt(3) and be done with it. (But, without having looked, I'd bet
that getopt(3) uses the above algorithm as well.)

Agreed.
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt

S
 
J

James Kuyper

I thought using a loop to "consume" switches by modifying argv/argc,
leaving only the filenames that follow (if any), was the canonical way
of processing command lines.

With call by value, argc and argv are local copies, so there should
not be any problem modifying them.

It is better not to modify argv for any i, and even more, not modify
*argv, but as I understand it, it is legal for unix. (With some
restrictions that I don't know about.)


The following rules are set by the C standard, and are not UNIX-specific:

"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." (5.1.2.2.1p2)

Thus, the standard guarantees that you can modify argv and argv[j]
(for appropriate values of i and j), but you don't have permission to
modify argv.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top