D
Don
argc can be 0 with *argv == NULL on some systems. When that happens,
argv may be a pointer to (the start of) a single-element array in
which case *++argv does step outside the array.
Really? The program could be executed without its own name ever being
called?
Yes, you need to test *argv for NULL or, alternatively, for argc being
0. This makes me wonder why you don't!
Well, I did, later on.
What do you all think of this?
*******
while (*(++argv) != NULL && *argv[0] == '-') {
You have to test *argv not *++argv. This alters almost everything
that follows, though you'll get away with it if there is always a
non-NULL argv[0].
I thought that there *was* always a non-NULL argv[0]. K&R sayeth, "By
convention, argv[0] is the name by which the program was invoked, so
argc is at least 1." Granted, that's not a statement of the standard,
but I'm having a hard time seeing how a program can be invoked without
it being invoked by some name, which would be argv[0].
*******
while (*argv != NULL && *argv[0] == '-') {
*******
Isn't that redundant anyway, though? If *argv[0] == '-', then we know
that *argv isn't null. But say I increment argv elsewhere; won't it
fail on the very first loop, unless it's called with a name beginning
with '-'?
What about the following:
*******
while (--argc > 0 && (*++argv)[0] == '-') {
}
if (isdigit((*argv+1)[1]) || (*argv+1)[1] == '.')
I don't think you meant that. argv[0][1] is the character that
follows the '-' you have just identified in the 'while' test. If you
want to write that with fewer indexes, that would be *(argv[0] + 1) or
*(*argv + 1) or (*argv + 1)[0] but argv[0][1] is so much clearer than
any of the alternatives. (*argv + 1)[1] is the second digit. Did you
test with single digit negative number?
Yes; haven't figured that one out yet.
break; /* negative numbers are not optional args */
while (c = *++argv[0])
Whilst I don't object to modifying argv, modifying argv[0] worries me
a little. It's permitted, but it complicates matters (debugging in
particular) so I prefer to set a 'flags' pointer to the current arg
and "walk" that.
switch (c) {
default:
fprintf(stderr,"dec: illegal option \"%c\"\n",c);
break;
}
}
if (*argv != NULL) {
printf("%f\n",doztodec(*(argv)));
return 0;
}
while (getword(doznum,MAXLINE) != EOF) {
printf("%f\n",doztodec(doznum));
}
return 0;
<snip>