The different ways to use argv

Discussion in 'C Programming' started by GWTNewbie, Apr 11, 2013.

  1. GWTNewbie

    GWTNewbie Guest

    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?
    GWTNewbie, Apr 11, 2013
    #1
    1. Advertising

  2. GWTNewbie

    Jorgen Grahn Guest

    On Thu, 2013-04-11, GWTNewbie wrote:
    ....
    > 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

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Apr 11, 2013
    #2
    1. Advertising

  3. GWTNewbie

    John Gordon Guest

    In <> GWTNewbie <> writes:

    > 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

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
    John Gordon, Apr 11, 2013
    #3
  4. GWTNewbie

    Les Cargill Guest

    GWTNewbie wrote:
    > 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...

    --
    Les Cargill
    Les Cargill, Apr 11, 2013
    #4
  5. On 11-Apr-13 12:48, Les Cargill wrote:
    > GWTNewbie wrote:
    >> 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

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Apr 11, 2013
    #5
  6. On 11-Apr-13 11:34, GWTNewbie wrote:
    > 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

    --
    Stephen Sprunk "God does not play dice." --Albert Einstein
    CCIE #3723 "God is an inveterate gambler, and He throws the
    K5SSS dice at every possible opportunity." --Stephen Hawking
    Stephen Sprunk, Apr 11, 2013
    #6
  7. Stephen Sprunk <> wrote:
    > On 11-Apr-13 12:48, Les Cargill wrote:
    >> GWTNewbie wrote:
    >>> 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
    glen herrmannsfeldt, Apr 11, 2013
    #7
  8. GWTNewbie

    Les Cargill Guest

    Stephen Sprunk wrote:
    > On 11-Apr-13 12:48, Les Cargill wrote:
    >> GWTNewbie wrote:
    >>> 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
    >

    --
    Les Cargill
    Les Cargill, Apr 11, 2013
    #8
  9. GWTNewbie

    James Kuyper Guest

    On 04/11/2013 06:29 PM, glen herrmannsfeldt wrote:
    > Stephen Sprunk <> wrote:

    ....
    >> 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.
    --
    James Kuyper
    James Kuyper, Apr 12, 2013
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bret

    char **argv vs. char* argv[]

    Bret, Aug 31, 2003, in forum: C Programming
    Replies:
    21
    Views:
    4,557
    Richard Heathfield
    Sep 3, 2003
  2. David
    Replies:
    10
    Views:
    5,922
    Richard Heathfield
    Sep 15, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,614
    Old Wolf
    Jan 20, 2004
  4. =?ISO-8859-1?Q?Thomas_N=FCcker?=

    sys.argv[0] - 'module' object has no attribute 'argv'

    =?ISO-8859-1?Q?Thomas_N=FCcker?=, Jun 30, 2003, in forum: Python
    Replies:
    0
    Views:
    886
    =?ISO-8859-1?Q?Thomas_N=FCcker?=
    Jun 30, 2003
  5. jab3

    char **argv & char *argv[]

    jab3, Dec 4, 2004, in forum: C Programming
    Replies:
    5
    Views:
    650
    Chris Torek
    Dec 8, 2004
Loading...

Share This Page