1.linux的命令列解析引數之getopt_long函式

yanghangwww發表於2019-12-21

1.函式原型:
#include <unistd.h>

extern char *optarg;
extern int optind, opterr, optopt;
#include <getopt.h>
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

2.說明:
1、argc和argv和main函式的兩個引數一致。
2、optstring: 表示短選項字串。
"abc:d:012f::"代表:可以支援的短選項有: -a -b -c -d -0 -1 -2 -f等
(1)只有一個字元,不帶冒號-----只表示選項,例如: -d
(2)一個字元+一個冒號:表示選項後棉帶一個引數,例如:-c 123
(3)一個字元+兩個冒號:表示選項後面可以帶一個可選引數,如果帶引數,則不能有空格,例如:-f789
3、longopts:表示長選項結構體:

	struct option 
	{  
		 const char *name;  
		 int         has_arg;  
		 int        *flag;  
		 int         val;  
	};  
	
    struct option long_options[] = {
        {"add",     required_argument, NULL,  0 },
        {"append",  no_argument,       NULL,  0 },
        {"delete",  required_argument, NULL,  0 },
        {"verbose", no_argument,       NULL,  0 },
        {"create",  required_argument, NULL, 'c'},
        {"file",    required_argument, NULL,  0 },
		{"test1",    no_argument, &lopt,  1 },
		{"test2",    no_argument, &lopt,  2 },
		{"test3",    no_argument, &lopt,  3 },
        {0,         0,                 0,  0 }	//最後一行必須為零,否則段錯誤
    };
	(1)name:
		表示長選項的名稱,如:add、append
	(2)has_arg:
		no_argument(或者是0)時:後面不跟引數,eg:--help
		required_argument(或者是1)時:後面跟引數,eg:--add=123 /--add 123
		optional_argument(或者是2)時:後面跟引數,eg:--add=123
		
	(3)flag:
		flag為NULL,返回val的值;
		flag不為NULL: getopt_long 函式將返回0,且將flag指標指向val(等同於返回val的值)
	(4)val:函式的返回值;
	
4.longindex	:
	指向當前長選項的第幾個值,從0開始,即long_options的下標值:
	
5.全域性變數:
	(1)optarg:當前選項的引數值
	(2)optind:表示下一個將被處理到的引數在argv中的下標值:


```c
#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>
 
int main(int argc, char **argv)
{
    int c;
    int digit_optind = 0;

 
   while (1) 
   {
		int lopt = 0;
        int option_index = 0;
		
        struct option long_options[] = {
            {"add",     required_argument, NULL,  0 },
            {"append",  no_argument,       NULL,  0 },
            {"delete",  required_argument, NULL,  0 },
            {"verbose", no_argument,       NULL,  0 },
            {"create",  required_argument, NULL, 'c'},
            {"file",    required_argument, NULL,  0 },
			{"test1",    no_argument, &lopt,  1 },
			{"test2",    no_argument, &lopt,  2 },
			{"test3",    no_argument, &lopt,  3 },
            {0,         0,                 0,  0 }
        };

	   printf("[%s:%d]:[yang] -------------------- optind = %d\n",__FUNCTION__,__LINE__,optind);
	   printf("[%s:%d]:[yang] optarg = %s\n",__FUNCTION__,__LINE__,optarg);

       c = getopt_long(argc, argv, "abc:d:012f::", long_options, &option_index);	   

	   printf("[%s:%d]:[yang] c = %d,c = %c, option_index = %d\n",__FUNCTION__,__LINE__,c,c,option_index);
	   
        if (c == -1)
            break;
 
       switch (c) 
	   {
        case 0:	//長引數 --
        	printf("option %s", long_options[option_index].name);

			if (optarg)
                printf(" with arg %s", optarg);
            printf("\n");
			
			switch (lopt) 
			{
				case 1:
					printf("long option lopt = %d\n", lopt);
					break;
				case 2:
					printf("long option lopt = %d\n", lopt);
					break;
				case 3:
					printf("long option lopt = %d\n", lopt);
					break;				
				default:
					printf("long option default\n");
					break;						
			}
            break;
 
       	case '0':
        case '1':
        case '2':
            printf("option %c\n", c);
            break;
 
       case 'a':
            printf("option a\n");
            break;
 
       case 'b':
            printf("option b\n");
            break;
 
       case 'c':
            printf("option c with value '%s'\n", optarg);
            break;
 
       case 'd':
            printf("option d with value '%s'\n", optarg);
            break;
			
       case 'f':
	   		if (optarg)
            	printf("option f with value '%s'\n", optarg);
			else
				printf("option f with no value \n");
            break;
 
       case '?':
            break;
 
       default:
            printf("?? getopt returned character code 0%o ??\n", c);
        }
    }


	printf("[%s:%d]:[yang] optind = %d\n",__FUNCTION__,__LINE__,optind);
	printf("[%s:%d]:[yang] argc = %d\n",__FUNCTION__,__LINE__,argc);
	
	if (optind < argc) 
	{
		printf("non-option ARGV-elements: ");

		while (optind < argc)
		printf("%s ", argv[optind++]);

		printf("\n");
	}
 	
   	exit(EXIT_SUCCESS);
   
}


列印結果:
aston@ubuntu:/mnt/hgfs/share/source_insight2/main_0$ ./app.out --add=123 --append --test1 -0 -f456 -a
[main:29]:[yang] -------------------- optind = 1
[main:30]:[yang] optarg = (null)
[main:34]:[yang] c = 0,c = , option_index = 0
option add with arg 123
long option default
[main:29]:[yang] -------------------- optind = 2
[main:30]:[yang] optarg = 123
[main:34]:[yang] c = 0,c = , option_index = 1
option append
long option default
[main:29]:[yang] -------------------- optind = 3
[main:30]:[yang] optarg = (null)
[main:34]:[yang] c = 0,c = , option_index = 6
option test1
long option lopt = 1
[main:29]:[yang] -------------------- optind = 4
[main:30]:[yang] optarg = (null)
[main:34]:[yang] c = 48,c = 0, option_index = 0
option 0
[main:29]:[yang] -------------------- optind = 5
[main:30]:[yang] optarg = (null)
[main:34]:[yang] c = 102,c = f, option_index = 0
option f with value '456'
[main:29]:[yang] -------------------- optind = 6
[main:30]:[yang] optarg = 456
[main:34]:[yang] c = 97,c = a, option_index = 0
option a
[main:29]:[yang] -------------------- optind = 7
[main:30]:[yang] optarg = (null)
[main:34]:[yang] c = -1,c = �, option_index = 0
[main:103]:[yang] optind = 7
[main:104]:[yang] argc = 7







相關文章