C++解析命令行

原文链接: https://blog.csdn.net/afei__/article/details/81261879

参考博文链接 :

https://blog.csdn.net/afei__/article/details/81261879  (C/C++ 命令解析:getopt 方法详解和使用示例)

https://www.cnblogs.com/Ran-Chen/p/9387899.html (C++中 int main(int argc, char **argv) 命令行传递参数)

https://blog.51cto.com/speakingbaicai/1074671 (示例)

一、简介
getopt() 方法是用来分析命令行参数的,该方法由 Unix 标准库提供,包含在 头文件中。

也就是下面的这句话要在最前面 

#include 

二、定义

int getopt(int argc, char * const argv[], const char *optstring);

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

getopt 参数说明:

argc:通常由 main 函数直接传入,表示参数的数量
argv:通常也由 main 函数直接传入,表示参数的字符串变量数组
optstring:一个包含正确的参数选项字符串,用于参数的解析。

例如 “abc:d::”,其中 -a,-b 就表示两个普通选项,-c 表示一个必须有参数的选项,因为它后面有一个冒号,后面跟的参数和c可以有空格或没有;-d也是必须有参数的选项,后面有两个冒号,表示后面的参数必须紧跟d。


外部变量说明:

optarg:如果某个选项有参数,这包含当前选项的参数字符串
optind:argv 的当前索引值
opterr:正常运行状态下为 0。非零时表示存在无效选项或者缺少选项参数,并输出其错误信息
optopt:当发现无效选项字符时,即 getopt() 方法返回 ? 字符,optopt 中包含的就是发现的无效选项字符
 

这个示例能详细说明各个外部参数的含义:

#include 
 
int main(int argc, char **argv) 
{ 
    int opt;
    opterr = 0; 
    
    while( (opt = getopt(argc, argv, "ab:c::d::")) != -1 ) 
    { 
         switch(opt) 
          { 
              case 'a': 
                  printf("option=a, opt=%d, optarg=%s, optind=%d, optopt=%d\n", opt, optarg, optind, optopt); 
                  break; 
              case 'b': 
                  printf("option=b, opt=%d, optarg=%s, optind=%d, optopt=%d\n", opt, optarg, optind, optopt); 
                    break; 
              case 'c': 
                  printf("option=c, opt=%d, optarg=%s, optind=%d, optopt=%d\n", opt, optarg, optind, optopt); 
                     break; 
              case 'd': 
                  printf("option=d, opt=%d, optarg=%s, optind=%d, optopt=%d\n", opt, optarg, optind, optopt); 
                     break; 
              case '?': 
                  printf("option=?, opt=%d, optarg=%s, optind=%d, optopt=%d\n", opt, optarg, optind, optopt); 
                   break; 
                default: 
                  printf("option=default, opt=%d, optarg=%s, optind=%d, optopt=%d\n", opt, optarg, optind, optopt); 
                     break; 
          } 
    } 
    return 0; 
} 


/*

root@ubuntu:~/eclipseworkspace# ./a.out -a -b barg -ccarg -ddarg
option=a, opt=97, optarg=(null), optind=2, optopt=0
option=b, opt=98, optarg=barg, optind=4, optopt=0
option=c, opt=99, optarg=carg, optind=5, optopt=0
option=d, opt=100, optarg=darg, optind=6, optopt=0


root@ubuntu:~/eclipseworkspace# ./a.out -a
option=a, opt=97, optarg=(null), optind=2, optopt=0


root@ubuntu:~/eclipseworkspace# ./a.out -ccarg
option=c, opt=99, optarg=carg, optind=2, optopt=0


root@ubuntu:~/eclipseworkspace# ./a.out -c carg
option=c, opt=99, optarg=(null), optind=2, optopt=0


root@ubuntu:~/eclipseworkspace# ./a.out 
root@ubuntu:~/eclipseworkspace# ./a.out a
root@ubuntu:~/eclipseworkspace# ./a.out -b barg
option=b, opt=98, optarg=barg, optind=3, optopt=0


root@ubuntu:~/eclipseworkspace# ./a.out -b
option=?, opt=63, optarg=(null), optind=2, optopt=98


root@ubuntu:~/eclipseworkspace# ./a.out -b -c
option=b, opt=98, optarg=-c, optind=3, optopt=0

这边穿插一下,C++中,比较常见的是不带参数的主函数int main(),如果使用命令行执行程序,主函数也可以接收预先输入的参数,形式如下。

int main(int argc,char **argv)

  • argc:命令行参数个数(Argument Count)
  • argv:命令行参数向量(Argument Vector)

例如,我们在命令行输入Project.exe string1 string2 string3时,argc=4,表示输入的参数个数是4,分别是Project.exestring1string2string3

argv是一个字符串数组,对应存储这4个字符串,即argv[0] = "Project.exe", argv[1] = "string1", argv[2] = "string2", argv[3] = "string3"。因此可以在主函数中,后续通过argc和argv获取参数信息。

int main(int argc,char **argv)也可以写成int main(int argc, char *argv[])。

 

三、实例分析
让我们通过一系列的实例来掌握 getopt 方法的使用吧。

1. 简单实例
OptDemo.c 如下:

#include 
#include 
 
int main(int argc, char *argv[]) {
    int o;
    const char *optstring = "abc:"; // 有三个选项-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 '?':
                printf("error optopt: %c\n", optopt);
                printf("error opterr: %d\n", opterr);
                break;
        }
    }
    return 0;
}


编译和运行:

分析:

命令 gcc OptDemo.c -o OptDemo 是使用 gcc 把 OptDemo.c 编译成可执行程序,命名为 OptDemo

第一次运行 ./OptDemo -a -b -c afei 正常执行和输出

第二次运行 ./OptDemo -abc 由于选项 c 后没有输入参数,于是报错

第三次运行 ./OptDemo -d 由于选项 d 不是我们在 optstring 中预定义的选项,于是报错

 

2. 可选参数
一个冒号表示选项后必须有参数,没有参数就会报错。如果有两个冒号的话,那么这个参数就是可选参数了,即可有可没有。
OptDemo.c 如下:

#include 
#include 
 
void usage() {
    printf("Usage:\n");
    printf("\tOptDemo [-a] [-b] [-c message]");
}
 
int main(int argc, char *argv[]) {
    int o;
    const char *optstring = "abc::"; // 有三个选项-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 '?':
                printf("发生错误时提示用户正确的使用方式\n");
                usage(); // 提示使用说明
                break;
        }
    }
    return 0;
}


编译和运行:

分析:

注意这里 可选参数 选项 -c 后面跟参数的时候,一定不能有空格。

但是如果是 必选参数,即选项后面只有一个冒号,则是有没有空格都可以。

 

3. 输入字符串转 int
由于 optarg 都是字符串类型的,所以当我们想要整型的输入参数时,会经常用到 atio() 这个方法,这里也简单介绍一下。
atoi (表示 ascii to integer) 是把字符串转换成整型数的一个函数,包含在 头文件中,使用方式如下:

int num = atoi(optarg);

 

你可能感兴趣的:(C++)