getopt(分析命令行参数)

  • 相关函数表头文件
    #include<unistd.h>
  • 函数声明
    int getopt(int argc,char * const argv[ ],const char * optstring);
  • 全局变量

    extern char *optarg;

    extern int optind, opterr, optopt;  //索引/错误输出标志/最后一个未知选项

  • 函数说明
    getopt()用来分析命令行参数。参数argcargv是由main()传递的参数个数内容。参数optstring 则代表欲处理的选项字符串。此函数会返回在argv中下一个的选项字母,此字母会对应参数optstring 中的字母。如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。如果getopt()找不到符合的参数,则会打印出错信息,并将全域变量optarg设为“?”字符,如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。

getopt() 所设置的全局变量包括:

char *optarg——当前选项参数字串(如果有)。

int optind——argv的当前索引值。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在argv[optind]至argv[argc-1]中可以找到。

int opterr——这个变量非零时,getopt()函数为“无效选项”和“缺少参数选项,并输出其错误信息。

int optopt——当发现无效选项字符之时,getopt()函数或返回'?'字符,或返回':'字符,并且optopt包含了所发现的无效选项字符。

短参数的定义

getopt()使用optstring所指的字串作为短参数列表,象"1ac:d::"就是一个短参数列表。短参数的定义是一个-后面跟一个字母或数字,象-a,-b就是一个短参数。每个数字或字母定义一个参数。

其中短参数在getopt定义里分为三种:

1、不带值的参数,它的定义即是参数本身。

2、必须带值的参数,它的定义是在参数本身后面再加一个冒号。

3、可选值的参数,它的定义是在参数本身后面加两个冒号 。

在这里拿上面的"1ac:d::"作为样例进行说明,其中的1,a就是不带值的参数,c必须带值的参数,d可选值的参数。
  在实际调用中,-1 -a -c cvalue -d, -1 -a -c cvalue -ddvalue,-1a -ddvalue -c cvalue都是合法的。这里需要注意三点:

1、不带值的参数可以连写,象1a是不带值的参数,它们可以-1 -a分开写,也可以-1a-a1连写。

2、参数不分先后顺序,-1a -c cvalue -ddvalue-d -c cvalue -a1的解析结果是一样的。

3、要注意可选值的参数的参数之间不能有空格,必须写成-ddvalue这样的格式,如果写成-d dvalue这样的格式就会解析错误。

默认情况下getopt会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。

返回值

getopt()每次调用会逐次返回命令行传入的参数。
没有参数的最后的一次调用时,getopt()将返回-1
当解析到一个不在optstring里面的参数,或者一个必选值参数不带值时,返回?
当optstring是以:开头时,缺值参数的情况下会返回:,而不是?

范例

 #include <unistd.h>
#include <stdlib.h>
#include <stdio.h> int
main(int argc, char *argv[])
{
int opt; /*接收选项*/
extern char* optarg;/*指向当前getopt()返回选项的参数*/
extern int optopt; /*当选项没有出现在optstring中,或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?’*/
extern int opterr; /*用于控制getopt()是否打印出错信息*/
extern int optind; /*当前getopt()返回选项的下一个选项的索引(argv数组)*/ opterr = ; /*不要打印出错信息*/ while ((opt = getopt(argc, argv, "a1b:c::")) != -) {
/* a和1为不带参数选项,b为必须带一个参数选项,c为可选参数选项(注意参数与-c直接不能分开) */
/* 示例: getopt -a -b 100 -c12 */
switch (opt) {
case 'a':
case '':
printf("选项: %c\n",opt);
break;
case 'b':
printf("选项: b,带的参数是 %s\n",optarg);
break;
case 'c':
printf("选项: c,带的参数是 %s\n",optarg);
break;
default: /* '?' */
if(optopt == 'c'){
printf("选项: c,没有带参数\n");
break;
}
fprintf(stderr, "用法: %s [-1a] [-c [argument]] [-b argument]\n",
argv[]);
exit(EXIT_FAILURE); //无效的参数,退出程序
}
}
printf("optind=%d\n",optind); //在命令行选项参数再也检查不到optstring中包含的选项时,
//返回-1,同时optind储存第一个不包含选项的命令行参数。
//getopt 中指的 选项是指以 `-`开头的
if (optind >= argc) {
fprintf(stderr, "选项索引超过了argv数组的长度\n");
exit(EXIT_FAILURE);
}
//输出第一个不包含选项的参数
printf("非选项参数 = %s\n", argv[optind]); //输出一下命令行参数,看看是否被改变
for(opt = ; opt < argc ; ++opt){
printf("索引:%d\t\t命令行参数:%s\n",opt,argv[opt]);
} exit(EXIT_SUCCESS); //成功退出
}

getopt示例代码

执行:

fx@fx:~/code$ ./getopt -a -b  -c12
选项: a
选项: b,带的参数是
选项: c,带的参数是
optind=
选项索引超过了argv数组的长度
fx@fx:~/code$ ./getopt -a 哈哈 -b -c12
选项: a
选项: b,带的参数是
选项: c,带的参数是
optind=
非选项参数 = 哈哈
索引: 命令行参数:./getopt
索引: 命令行参数:-a
索引: 命令行参数:-b
索引: 命令行参数:
索引: 命令行参数:-c12
索引: 命令行参数:哈哈

getopt_long示例代码

 #include <unistd.h>
#include <stdlib.h>
#include <stdio.h> extern int optind, opterr, optopt; int
main(int argc, char **argv)
{
int c; /* 用于接收字符选项 */
int digit_optind = ; /* 用于接收数字选项 */ while () {
/* */
int this_option_optind = optind ? optind : ;
int option_index = ;
/* 长选项结构体数组 */
static struct option long_options[] = {
{"add", required_argument, , }, //需要一个参数
{"append", no_argument, , }, //没有参数
{"delete", required_argument, , },
{"verbose", no_argument, , },
{"create", required_argument, , 'c'}, //返回字符'c'
{"file", required_argument, , },
{, , , }
};
/*
struct option {
const char *name; //选项名称
int has_arg; //参数标志(no_argument/0没有参数;required_argument/1需要一个参数;optional_argument/2一个可选参数)
int *flag; //指定如何返回一个较长的选项。当这个指针为空的时候,函数直接将val的数值从getopt_long的返回值返回出去,当它非空时,val的值会被赋到flag指向的整型数中,而函数返回值为0
int val; //用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值。
};
*/
/* 获取一个选项 */
c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index); if (c == -){ /* 无参数可获取了 */
break;
} switch (c) { /* 获取参数解析 */
case :
printf("选项是:%s", long_options[option_index].name);
if (optarg){ /*如果是带参数的选项 */
printf(" 参数是: %s", optarg);
}
printf("\n");
break; case '':
case '':
case '':
if (digit_optind != && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("选项: %c\n", c);
break; case 'a':
printf("选项: a\n");
break; case 'b':
printf("选项: b\n");
break;
case 'c':
printf("选项: c 带的值: '%s'\n", optarg);
break; case 'd':
printf("选项: d 带的值: '%s'\n", optarg);
break; case '?':
break; default:
printf("?? getopt 返回字符代码 0%o ??\n", c);
}
} if (optind < argc) {
printf("非选项的命令行参数项: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}
exit(EXIT_SUCCESS);
}

getopt_long示例代码

getopt函数的使用——分析命令行参数的更多相关文章

  1. 【转】getopt分析命令行参数

    (一) 在Linux中,用命令行执行可执行文件时可能会涉及到给其加入不同的参数的问题,例如: ./a.out -a1234 -b432 -c -d 程序会根据读取的参数执行相应的操作,在C语言中,这个 ...

  2. getopt 分析命令行参数 -n -t 1

    在Linux中,我们常常用到 ls -l 等等之类带有选项项的命令,下面,让我们用C++来实现该类似的命令. 在实现之前,首先,我们来介绍一下一个重要函数:getopt() 表头文件 #include ...

  3. getopt(分析命令行参数)

    ref:http://vopit.blog.51cto.com/2400931/440453   相关函数表头文件         #include<unistd.h>定义函数       ...

  4. boost 分析命令行参数

    #include <boost/program_options.hpp> #include <iostream> #include <vector> using n ...

  5. 命令行参数解析函数getopt和getopt_long函数【转】

    原文地址:http://blog.csdn.net/cashey1991/article/details/7942809 getopt和getopt_long函数   平时在写程序时常常需要对命令行参 ...

  6. 解析main函数的命令行参数

    原创文章,转载请正确注明本文原始URL及作者. 介绍 写C/C++程序,我们常常需要把main函数的参数作为选项来传递.在linux中,解析选项有专门的函数可以用. int getopt(int ar ...

  7. 转载:linux编程,命令行参数输入getopt

    下面资料来自百度百科: getopt(分析命令行参数) 相关函数 表头文件 #include<unistd.h> 定义函数 int getopt(int argc,char * const ...

  8. Shell 参数(2) --解析命令行参数工具:getopts/getopt

    getopt 与 getopts 都是 Bash 中用来获取与分析命令行参数的工具,常用在 Shell 脚本中被用来分析脚本参数. 两者的比较 (1)getopts 是 Shell 内建命令,geto ...

  9. python解析命令行参数

    常常需要解析命令行参数,经常忘记,好烦,总结下来吧. 1.Python 中也可以所用 sys 的 sys.argv 来获取命令行参数: sys.argv 是命令行参数列表 参数个数:len(sys.a ...

随机推荐

  1. Java工厂设计模式

    程序在接口和子类之间加入一个过渡类,通过此过渡类端取得接口的实例化对象,一般都会称这个过渡端为工厂类 //=============================================== ...

  2. 11 Clever Methods of Overfitting and how to avoid them

    11 Clever Methods of Overfitting and how to avoid them Overfitting is the bane of Data Science in th ...

  3. UI控件之ListView

    一,一个简单的TextView列表 public class FirstActivity extends Activity { private String[] data = {"Apple ...

  4. Python基础之【第二篇】

    一.作用域 对作用域来说,只要变量在内存里面存在就可以使用: ==: name = 'saneri' print name 二.三元运算 result = 值1 if 条件 else 值2 如果条件为 ...

  5. 整理一下Entity Framework的查询

    整理一下Entity Framework的查询 2012-08-30 13:41:59 标签:Entity Framework 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信 ...

  6. MVC中 _ViewStart _Layout Index三个页面中的加载顺序

    MVC学习中忽然想到一个问题.. 在访问一个Index.cshtml页面时, MVC的加载顺序是怎么样的呢? 首先说下我的结论 . _ViewStart.cshtml . Index.cshtml . ...

  7. PHP本地通过映射,实现多域名访问

    PHP本地通过映射,实现多域名访问 第一步:先在C盘下的windows/system32/drivers/etc/hosts文件加上 127.0.0.1       localhost    127. ...

  8. 如何才能实现在点击链接时直接在网页中打开word文档,但不提示保存

    一般要直接打开需要客户端 1.客户端有word支持 2.客户端浏览器的版本与设置 可寻找一下相关的控件或中间件,我的意见是看能否变通一下,把word转成HTML或PDF再展示给用户.(若用户不需要编辑 ...

  9. HITtrainning20140417题解

    题目列表:     ID Origin Title 10 / 15 Problem A FZU 2152 文件系统   0 / 16 Problem B FZU 2153 A simple geome ...

  10. Django 部署

    话说这个部署挺折腾人的,先开始使用 mod_python ,貌似版本一直有问题,没成功过,以后再试. 使用 mod_wsgi 成功,记录如下: 1.下载 mod_wsgi: http://code.g ...