Thread: Pointers and parameters in the command line

  1. #1
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193

    Pointers and parameters in the command line

    Good afternoon.

    Code:
    /* 
     * **************************** how to run *******************************
     * in the command line: 
     * 
     * 1) [Executable] -x [pattern] 
     * - Only words which don't match the pattern are going to be printed   
     * -x is the "except" parameter
     * 
     * 2) [Executable] -x -n [pattern]
     * Words that don't match the pattern are going to be printed numerically
     * 
     * 3) [Executable] -n [pattern]
     * The words that match the pattern are going to be printed numerically
     * ***********************************************************************
     */
    
    /* I didn't understand how those two while work 
     
     * argv[0] is the name of the executable, right? 
     * is (*++argv)[0] incrementing the pointer to argv[1] (-n or -x) 
     * and accessing the first value pointed ? (-) 
     * 
     * Due to that, I thought *++argv[0] was doing the same of (*++argv)[0] because that 
     * increments the pointer to point to the first value of the parameter argv[1] which 
     * is '-'. How does it point to 'n' or 'x' ? 
     */ 
    
    #include <stdio.h> 
    #include <string.h> 
    
    #define MAXLINE 1000
    
    int getLine(char s[], int lim) 
    { 
       int i,c; 
       for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) 
       { 
          s[i] = c;   
       }
       if(c == '\n') 
       { 
         s[i] = c;  
         ++i; 
       }
       s[i] = '\0'; 
       return i;                      
    }
    
    int main(int argc, char* argv[]) 
    { 
      char line[MAXLINE];
      long lineno = 0;
      int c, except = 0, number = 0, found = 0;
      
      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;
         }
      if(argc != 1) 
        printf("Usage: find -x -n pattern\n");             
      else 
        while(getLine(line, MAXLINE) > 0)
        { 
          lineno++;
          if((strstr(line, *argv) != NULL) != except)
          { 
            if(number) 
              printf("%ld:", lineno);
            printf("%s", line);
            found++;    
          }               
        }       
      return found;    
    }
    Last edited by thames; 12-03-2012 at 09:04 AM. Reason: forgot to include getLine

  2. #2
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by thames View Post
    Good afternoon.

    I didn't understand how those two while work

    argv[0] is the name of the executable, right?
    is (*++argv)[0] incrementing the pointer to argv[1] (-n or -x)
    and accessing the first value pointed ? (-)

    Due to that, I thought *++argv[0] was doing the same of (*++argv)[0] because that
    increments the pointer to point to the first value of the parameter argv[1] which
    is '-'. How does it point to 'n' or 'x' ?
    The purpose of the two while loops is to loop through command-line switches. Consider you have the program foo.c and you run it like so:
    Code:
    Foo.exe -xyz -a -b -c bar.c
    What will be the contents of argc and argv as you enter main?
    Code:
    //argc: 6
    //argv: {"Foo.exe", "-xyz", "-a", "-b", "-c", "bar.c"}
    
    Now consider the two while loops:
    Code:
        while (--argc > 0 && (*++argv)[0] == '-')
            while ((c = *++argv[0]))
                printf("got c: %c\n", c);
    The outer loop says to loop through all arguments (starting with argv[1]) as long as the argv begins with '-'. The inner loop says to loop through all characters in that argument (for example, "-xyz") and process each one.

    Notice in the inner while loop, the [0] part takes precedence over the ++, so it first dereferences argv into a single argument and THEN increments to the next character with ++ (i.e. skipping the '-'). The inner while loop may also be written like this:
    Code:
            while ((c = *++(*argv)))

  3. #3
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193
    Quote Originally Posted by c99tutorial View Post
    Code:
            while ((c = *++(*argv)))
    I'm following ... but why is argv[0] being dereferenced instead of argv[1]? to me, argv[0] is the name of the program.

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    As you first enter main, your argc and argv look like this:

    Code:
    //argc: 6 
    //argv: {"Foo.exe", "-xyz", "-a", "-b", "-c", "bar.c"}
    Then after the first while loop, --argc and ++argv modify them, so now they look like this:

    Code:
    
    //argc: 5 
    //argv: {"-xyz", "-a", "-b", "-c", "bar.c"}
    So argv[0] (or equivalently, *argv) always refers to the "current" argument being processed.

  5. #5
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193
    The outer while loops through all the arguments
    The second while loops through all the characters
    and I have to consider that argc is tricky.

    Many thanks. I got that.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    argv is not really tricky, most people are just interested in looking cool. What might be easier on the brain is:
    Code:
    #include <stdio.h>
    int main(int argc, const char *const *argv)
    {
        char c;
        int i;
    
        for (i = 1; i < argc; i++) {
            const char *p = argv[i];
    
            if (*p == '-') {
                ++p;
            }
            else {
                break;
            }
    
            while ((c = *p++) != '\0') {
                printf("got c: %c\n", c);
            }
        }
    
        return 0;
    }

  7. #7
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193
    considering this section:

    Code:
      
      if((strstr(line, *argv) != NULL) != except)
          { 
            if(number) 
              printf("%ld:", lineno);
            printf("%s", line);
            found++;    
          }
    I didn't understand how can be possible to print the line when the parameter is -x. After all, the expression will be equal to except when I set this flag, right?

  8. #8
    Registered User
    Join Date
    Nov 2012
    Posts
    32
    Code:
      
      if((strstr(line, *argv) != NULL) != except)
    It's my favorite program's line from K&R
    Let's suppose that except is 1:
    Code:
      
      if((strstr(line, *argv) != NULL) != 1)
    Then this line is equivalent to
    Code:
      
      if((strstr(line, *argv) != NULL) == 0)
    (because result of strstr(line, *argv) != NULL is 0 or 1)

    This line is equivalent to
    Code:
      
       if((strstr(line, *argv) == NULL))
    That is, if the text's line doesn't include the pattern (*argv), then print this line.

  9. #9
    Tears of the stars thames's Avatar
    Join Date
    Oct 2012
    Location
    Rio, Brazil
    Posts
    193
    (because result of strstr(line, *argv) != NULL is 0 or 1)

    I liked that! when the flags are different to denote the desired situation.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. command line parameters
    By CppProgrammer33 in forum C++ Programming
    Replies: 16
    Last Post: 08-23-2010, 05:38 PM
  2. Command line parameters
    By gamebrigada in forum C Programming
    Replies: 1
    Last Post: 08-21-2009, 04:48 PM
  3. command line parameters
    By gvector1 in forum C# Programming
    Replies: 1
    Last Post: 06-02-2003, 09:12 AM
  4. command line parameters
    By Shadow in forum C Programming
    Replies: 2
    Last Post: 05-21-2002, 04:33 PM
  5. command-line parameters.
    By Tombear in forum C Programming
    Replies: 2
    Last Post: 10-28-2001, 08:40 AM