Loading

命令行参数的实现(C语言)

命令行参数的实现(C语言)

一、引入

我们在使用可执行程序的时候,经常会加入一些可选旗标,以实现精确的目标结果。

例如:在windows环境下运行ping -t www.baidu.com,其中-t就是可选旗标,通过命令行参数传入可执行程序

二、验证

#include <stdio.h>
 
int main(int argc, char *argv[])
{
    printf("参数数量argc = %d\n", argc);
	int i;
	for(i = 0; i < argc; i++)
	{
		printf("argv[%d] : %s\n", i, argv[i]);
	}
	return 0;
}

由打印结果可知,默认只有一个参数,可执行程序作为第一个参数传入。

添加参数:

由打印结果可知,第一个参数还是可执行程序,接下来的参数默认以空格隔开

三、解析

案列:输入旗标-title以及值,程序能解析出来

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
        printf("参数数量argc = %d\n", argc);
        if(argc > 3)//要实现带参数,需要满足参数基本数量
        {
                int i;
                for(i = 0; i < argc; i++)
                {
                        //printf("argv[%d] : %s\n", i, argv[i]);
                        if(0 == strcmp("-title", argv[i]) && strlen(argv[i+1]) > 0)
                        {
                                printf("The program %s\n", argv[i+1]);
                        }
                }
        }
        return 0;
}

---分割线---
2024-03-30 补充

一、相关头文件和全局变量

getopt()函数只能处理短选项,而getopt_long()函数两者都可以。可以说getopt_long()包含了getopt()。

#include <unistd.h>
#include <getopt.h>

extern char *optarg;
extern int optind, opterr, optopt;

/* 函数原型声明 */
int getopt(int argc, char * const argv[], const char *optstring);
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char *const argv[], const struct option *longopts, int *longindex);

注意:1、longopts的最后个元素必须是全0填充,否则会报段错误。2、短选项中每个选项都是唯一的。而长选项如果简写,需要保持唯一性。

1.1 全局变量说明

  • optarg :表示当前选项对应的参数值
  • optind:表示的是下一个将被处理到的参数在argv中的下标值
  • opterr:表示opterr = 0,在getopt、getopt_long、getopt_long_long遇到错误将不会输出到错误信息标准输出流。opterr在非0时,向屏幕输出错误。
  • optopt:表示没有被未标识的选项

1.2 函数参数说明

  • optstring : 表示短选项字符串

    形式如“a:b::cd:“,分别表示程序支持的命令行短选项有-a、-b、-c、-d,冒号含义如下:
    (1)只有一个字符,不带冒号——只表示选项, 如-c 
    (2)一个字符,后接一个冒号——表示选项后面带一个参数,如-a 100
    (3)一个字符,后接两个冒号——表示选项后面带一个可选参数,即参数可有可无, 如果带参数,则选项与参数之间不能有空格
        形式应该如-b200
    
  • longopts:表示长选项结构体

    /*
     * name: 选项名称,例如help
     * has_arg: 是否携带参数,可选值有no_argument、required_argument、optional_argument
     * flag:若参数为空, 那么当选中某个长选项的时候,getopt_long返回val值(即opt=val)。
     		若参数不为空,那么当选中某个长选项的时候,getopt_long将返回0(即opt=0),并且将flag指针参数指向val值
     * val: 表示指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值val
    */
    struct option 
    {  
         const char *name;  
         int         has_arg;  
         int        *flag;  
         int         val;  
    };
    struct option long_options[] = {
    {"host",        required_argument, 0, 'h'},
    {"port",        required_argument, 0, 'p'},
    {"client_id",   required_argument, 0, 'i'},
    {"user",        required_argument, 0, 'u'},
    {"password",    required_argument, 0, 'P'},
    {"topic",       required_argument, 0, 't'},
    {"qos",         required_argument, 0, 'q'},
    {"keep_alive",  required_argument, 0, 'k'},
    {"help",        no_argument,       0,  1},
    {0,             0,                 0,  0}
    };
    

二、getopt()

测试用例:

#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
 
int main(int argc, char *argv[]) {
    int o;
    const char *optstring = "abc:d::"; // 有三个选项-abc,其中c选项后有冒号,所以后面必须有参数
    while ((o = getopt(argc, argv, optstring)) != -1) {
        switch (o) {
            case 'a':
                printf("opt is a, oprarg is: %s\n", optarg);
                break;
            case 'b':
                printf("opt is b, oprarg is: %s\n", optarg);
                break;
            case 'c':
                printf("opt is c, oprarg is: %s\n", optarg);
                break;
            case 'd':
                printf("opt is c, oprarg is: %s\n", optarg);
                break;
            case '?':
                printf("error optopt: %c\n", optopt);
                printf("error opterr: %d\n", opterr);
                break;
        }
    }
    return 0;
}

三、getopt_long()

测试用例:

#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 this_option_optind = optind ? optind : 1;
        int option_index = 0;
        static struct option long_options[] = {
            {"add",     required_argument, 0,  0 },
            {"append",  no_argument,       0,  0 },
            {"delete",  required_argument, 0,  0 },
            {"verbose", no_argument,       0,  0 },
            {"create",  required_argument, 0, 'c'},
            {"file",    required_argument, 0,  0 },
            {0,         0,                 0,  0 }
        };
 
       c = getopt_long(argc, argv, "abc:d:012",
                 long_options, &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");
            break;
 
       case '0':
       case '1':
       case '2':
            if (digit_optind != 0 && digit_optind != this_option_optind)
              printf("digits occur in two different argv-elements.\n");
            digit_optind = this_option_optind;
            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 '?':
            break;
 
       default:
            printf("?? getopt returned character code 0%o ??\n", c);
        }
    }
 
   if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }
 
   exit(EXIT_SUCCESS);
}

posted @ 2022-09-11 13:24  eiSouthBoy  阅读(492)  评论(0)    收藏  举报