Thread: getopt - parsing string as argument

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    110

    getopt - parsing string as argument

    I'm trying to write a program to take a string from the UNIX command line, and perform some operations on it depending on command line switches. The format is ./program -(options) (arguments) string, and there are two switches -a, and -b, which takes an integer argument. I'm using getopt in a while loop with a switch statement, but have no idea how to read the string from the command line. So far I have:

    Code:
    int main(int argc,char *argv[]){
    
    char sw; //stores switch
    char string[100]; //stores string
    int n; //stores integer argument for switch b
    
    opterr=0;
    
    while((sw=getopt(argc,argv,"ab:"))!=-1){
      switch(sw){
        case 'a': //performs a string operation
        return -1;
        case 'b': //performs a different string operation also using the argument for switch -b
        return -1;
        case '?': printf("Invalid switch entered, options are -a or -b");
        return -1;
      }
    }
    
    }
    for me to be able to perform the string operations I need to somehow read the string, and the argument for b into the variables string and n - I'm familiar with sscanf and fgets, but everything I tried ended up in an error.

    Can someone tell me how it's done?

    Thanks

  2. #2
    Registered User
    Join Date
    Feb 2009
    Posts
    138
    the command line strings are all in argv. i don't really understand your question.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    110
    I can get the code the recognise the different switches, but I don't know how to get the integer argument for b, and the string from the command line, using the format above. either -a or -b may be used, or both, and the string can be up to 100 characters long including spaces.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    From my "man 3 getopt":
    The option string optstring may contain the following elements: individ-
    ual characters, and characters followed by a colon to indicate an option
    argument is to follow. For example, an option string "x" recognizes an
    option ``-x'', and an option string "x:" recognizes an option and argu-
    ment ``-x argument''. It does not matter to getopt() if a following
    argument has leading white space.
    Presumably yours is similar, but you should check, of course.

  5. #5
    Registered User
    Join Date
    Feb 2009
    Posts
    138
    you're probably not using getopt the right way. i can tell for sure because i always did that kind of stuff manually.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char **argv)
    {
        int i;
        for (i = 1; i < argc; i++)
        {
            if (argv[i][0] == '-')
            {
                if (i+1 == argc || argv[i+1][0] == '-')
                {
                    printf("invalid switch entered, no arguments\n");
                    return EXIT_FAILURE;
                }
                if (argv[i][1] == 'a')
                    printf("argument for -a: %s\n", argv[++i]);
                else if (argv[i][1] == 'b')
                    printf("argument for -a: %s\n", argv[++i]);
                else
                {
                    printf("invalid switch entered, options are -a or -b\n");
                    return EXIT_FAILURE;
                }
            }
        }
        return EXIT_SUCCESS;
    }

  6. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    some more relevant info from the getopt() manpage.
    Code:
    The getopt() function shall return the next option character (if one is found) from argv that
    matches a character in optstring, if there is one that matches. If the option takes an argument, 
    getopt() shall set the variable optarg to point to the option-argument as follows:
    
    + If the option was the last character in the string pointed to by an element of argv, then optarg 
      shall contain the next element of argv, and optind shall be incremented by 2. If the resulting 
      value of optind is greater than argc, this indicates a missing option-argument, and getopt() 
      shall return an error indication.
    
    + Otherwise, optarg shall point to the string following the option character in that element of 
      argv, and optind shall be incremented by 1

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Code:
    #include <string.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) {
    	char *A;
    	int opt, B;
    	while ((opt=getopt(argc, argv, "a:b:"))>0)  switch (opt) {
    		case '?': puts("Bad argument"); break; 
    		case 'a': A=malloc(strlen(optarg));
    			strcpy(A,optarg); break;
    		case 'b': B=atoi(optarg); break;
    		default: break;
    	}
    	printf("%s %d\n",A,B);
    	free(A);
    	return 0;
    }
    Your option string in your original post is wrong. "ab:" means that a does not have an argument (it's just a switch). "a:b:" means a and b both have a parameter returned in the char* optarg.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    110
    Thanks for the replies. MK27, that's just what I was looking for, except I only want an argument after -b and not -a.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by bertazoid View Post
    Thanks for the replies. MK27, that's just what I was looking for, except I only want an argument after -b and not -a.
    Sorry, I though by "//performs a string operation" you meant "//performs a different string operation also using the argument for switch". Good luck.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    110
    I don't understand why I can't use optarg as an integer. Form one of the string operations I used:

    Code:
    for(i=0;i<optarg;i++){
      printf("%s",string);
    }
    and got a compiler error saying "warning: comparison between pointer and integer". I don't understand this since i is an integer as defined by me and so is optarg isn't it?...When I print optarg using printf("%d",optarg); it prints the integer entered at the command line as the argument for -b. i.e. -b 3, prints optarg as 3. So why is it different when I use it in the for loop? I also tried:

    Code:
    for(i=0;i<*optarg;i++){
      printf("%s",string);
    }
    and instead of printing the string three times, it printed it about 30 times.

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Did you read the manpage of getopt() yet? optarg is not an integer but a pointer to char and is declared externally.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    110
    I'm reading through it now finding it hard to get my head round.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by bertazoid View Post
    I don't understand why I can't use optarg as an integer. Form one of the string operations I used:

    Code:
    for(i=0;i<optarg;i++){
      printf("%s",string);
    }
    That's expected since optarg is of type char*.
    Quote Originally Posted by bertazoid View Post
    I also tried:
    Code:
    for(i=0;i<*optarg;i++){
      printf("%s",string);
    }
    and instead of printing the string three times, it printed it about 30 times.
    That 3 is not an integer but an ASCII character. It should print it about 50 times precisely.
    Last edited by itCbitC; 02-05-2009 at 01:58 PM.

  14. #14
    Registered User
    Join Date
    Oct 2008
    Posts
    110
    Ah ok now I get it. Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  2. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  3. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  4. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  5. can anyone see anything wrong with this code
    By occ0708 in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 12:47 PM