Processing command line arguments

G

Gregor H.

In K&R (2nd edition) the authors published the following code for
dealing with command line arguments (p. 117):

while (--argc > 0 && (*++argv)[0] == '-')
while (c = *++argv[0])
switch (c) {
case 'x':
except = 1;
break;
case 'n':
number = 1;
break;
default:
printf("find: illegal option %c\n", c);
argc = 0;
found = -1;
break;
}

But this solution raised some criticism:

"The sample program increments argv[0]. Although argv is
modifiable, and argv[0][0] is modifiable (if argv[0] is
not a null pointer), argv[0] is not modifiable. (At least,
not always.)"

(Peter Seebacher, http://www.plethora.net/~seebs/c/knr.html)

"p.117 (§5.10): In the find example, the program increments
argv[0]. This is not specifically forbidden, but not
specifically allowed either."

(Source:
Errata for The C Programming Language, Second Edition
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html)

Now my question is: would the following (slight modification of the
original code) be a reasonable (or at least correct) solution?:

while (--argc > 0 && (*++argv)[0] == '-') {
char *arg = *argv;
while (c = *++arg)
switch (c) {
case 'x':
except = 1;
break;
case 'n':
number = 1;
break;
default:
printf("find: illegal option %c\n", c);
argc = 0;
found = -1;
break;
}
}


G.
 
M

Malcolm McLean

Gregor H. said:
In K&R (2nd edition) the authors published the following code for
dealing with command line arguments (p. 117):

while (--argc > 0 && (*++argv)[0] == '-')
while (c = *++argv[0])
switch (c) {
case 'x':
except = 1;
break;
case 'n':
number = 1;
break;
default:
printf("find: illegal option %c\n", c);
argc = 0;
found = -1;
break;
}

But this solution raised some criticism:

"The sample program increments argv[0]. Although argv is
modifiable, and argv[0][0] is modifiable (if argv[0] is
not a null pointer), argv[0] is not modifiable. (At least,
not always.)"

(Peter Seebacher, http://www.plethora.net/~seebs/c/knr.html)

"p.117 (§5.10): In the find example, the program increments
argv[0]. This is not specifically forbidden, but not
specifically allowed either."

(Source:
Errata for The C Programming Language, Second Edition
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html)

Now my question is: would the following (slight modification of the
original code) be a reasonable (or at least correct) solution?:

while (--argc > 0 && (*++argv)[0] == '-') {
This line is virtually unreadable. I know K and R used the same construct.
Things have moved on.
char *arg = *argv;
while (c = *++arg)
However this is the way round. argv contains a list of strings. Nothing
conceptually difficult about that, but you can make it look difficult
because strigns are not atomic objects in C. It is a bad idea to modify the
strings in place, though I think they are writeable for historical reasons,
and it is a bad idea and may even be illegal to modify the pointers in the
argv array.
However if you take copies then you can do what you want with the copy,
naturally.
 
G

Guest

Gregor said:
In K&R (2nd edition) the authors published the following code for
dealing with command line arguments (p. 117):

while (--argc > 0 && (*++argv)[0] == '-')
while (c = *++argv[0])
switch (c) {
case 'x':
except = 1;
break;
case 'n':
number = 1;
break;
default:
printf("find: illegal option %c\n", c);
argc = 0;
found = -1;
break;
}

But this solution raised some criticism:

"The sample program increments argv[0]. Although argv is
modifiable, and argv[0][0] is modifiable (if argv[0] is
not a null pointer), argv[0] is not modifiable. (At least,
not always.)"

(Peter Seebacher, http://www.plethora.net/~seebs/c/knr.html)

"p.117 (§5.10): In the find example, the program increments
argv[0]. This is not specifically forbidden, but not
specifically allowed either."

(Source:
Errata for The C Programming Language, Second Edition
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html)

The criticisms are incorrect. The standard is poorly worded (and for
that reason, the issue has come up multiple times), but both the
intent and the literal wording are that there are no prohibitions
against modifying argv[0].

There are arguably stylistic problems, though, so you could use
something like

if (argc != 0)
{
char **argptr;
for (argptr = argv + 1; *argptr != NULL; argptr++)
{
char *arg = *argptr;
if (arg[0] != '-')
break;
/* ... */
}
}

which not only avoids the unclarity of modifying argv[0], but is also
easier to comprehend.
 
F

Francine.Neary

"Gregor H." <nomail@invalid> wrote in message

(Why did you start a new thread to reply to this question?)
In K&R (2nd edition) the authors published the following code for
dealing with command line arguments (p. 117):
while (--argc > 0 && (*++argv)[0] == '-')
while (c = *++argv[0])
switch (c) {
case 'x':
except = 1;
break;
case 'n':
number = 1;
break;
default:
printf("find: illegal option %c\n", c);
argc = 0;
found = -1;
break;
}
But this solution raised some criticism:
"The sample program incrementsargv[0]. Althoughargvis
modifiable, andargv[0][0] is modifiable (ifargv[0] is
not a null pointer),argv[0] is not modifiable. (At least,
not always.)"
"p.117 (§5.10): In the find example, the program increments
argv[0]. This is not specifically forbidden, but not
specifically allowed either."
(Source:
Errata for The C Programming Language, Second Edition
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html)
Now my question is: would the following (slight modification of the
original code) be a reasonable (or at least correct) solution?:
while (--argc > 0 && (*++argv)[0] == '-') {

This line is virtually unreadable. I know K and R used the same construct.
Things have moved on.

Say what? It's terse, clear, and correct - what more can you ask for
in a line of code?
 
G

Gregor H.

while (--argc > 0 && (*++argv)[0] == '-') { ... }
This line is virtually unreadable. I know K and R used the same construct.
Things have moved on.
Say what? It's terse, clear, and correct - what more can you ask for
in a line of code?
Agree with you. But maybe he would prefer the variant

while (--argc > 0 && **++argv == '-') { ... }

This way we do not mix pointer notation with index notation. Maybe
this is a "better" solution. Actually, I use _this variant_ in my
improved code. So *my* version actually is:

while (--argc > 0 && **++argv == '-') {
char *arg = *argv;
while (c = *++arg)
switch (c) {
case 'x':
except = 1;
break;
case 'n':
number = 1;
break;
default:
printf("find: illegal option %c\n", c);
...
break;
}
}


G.
 
F

Francine.Neary

while (--argc > 0 && (*++argv)[0] == '-') { ... }
This line is virtually unreadable. I know K and R used the same construct.
Things have moved on.
Say what? It's terse, clear, and correct - what more can you ask for
in a line of code?

Agree with you. But maybe he would prefer the variant

while (--argc > 0 && **++argv == '-') { ... }

This way we do not mix pointer notation with index notation. Maybe
this is a "better" solution.

Good point - you save a few characters doing it this way too :)
 

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

Similar Threads


Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top