getopt -- 解析命令的可选项
 
【说明】getopt只是一个简单的解析命令可选项的函数,只能进行简单的格式命令解析,格式如下:
 
1、形如:cmd [-a][-b] //对短选项的解析;
2、形如:cmd [-a a_argument][-b b_argument] //对短选项及短选项的参数解析;
3、形如:cmd [-a[a_argument]] //选项a的参数也是可选的情况解析
 
原型:
 
#include <unistd.h>

extern char *optarg;
extern int optind, opterr, optopt;
int getopt(int argc, char * const argv[], const char *optstring);
 
描述:
 
1、getopt函数解析命令行参数,argcargv是调用main函数时传入的参数。传入的'-'开始的字符被解析为选项,getopt一次执行解析出一个option,如果循环执行,可以将argv中的全部option解析出来;
2、在getopt的执行中,每次进入都会更新optind变量,该变量指向下一个argv参数;
3、如getopt返回-1,表示argv[]中的所有选项被解析出,optind指向第一个非选项的argument元素;这里要注意,在getopt执行过程中会将单独的argument交换到argv数组的后面,option选项提前,如:cmd -a file1 -b file2,如果a/b均为不带参数的选项,这最终argv数组变为:cmd -a -b file1 file2;
4、optstring指定选项合法的选项,一个字符代表一个选项,在字符后面加一个':'表示该选项带一个参数,字符后带两个':'表示该选项带可选参数(参数可有可无),若有参数,optarg指向该该参数,否则optarg为0;
5、前面说了getopt会进行argv顺序的调整,但也可以通过设置optstring改变它的方式,这里有两种:
     1) 如果optstring的第一个参数是'+'或者POSIXLY_CORRECT被设置,则getopt在原argv的顺序上遇到第一个非选项就返回-1;
     2) 如果optstring的第一个参数是'-',则会将所有的非选项当选项处理,并且返回1,用字符代码1表示该选项;
6、如果getopt不能识别一个选项字符,它会打印一个错误消息到stderr上,并将该字符存放到optopt中,返回'?';调用程序可以设置opterr=0设置不打印错误信息;注意:要使能打印错误信息,optstring的第一个字符(或者在第一个字符是+/-之后)不能是':',否则也不会打印错误;
7、如果optstring中指定了option需要参数,但在命令行没有参数,那么getopt将返回'?',如果在optstring的第一个字符(或者在第一个字符是+/-之后)是':',那么将返回':';
 
返回值:
 
1、返回类型为int,这个在编程的时候要注意,因为返回值类型范围要包含-1,很容易返回值接收定义为char,但在一些系统中char是无符号的,将导致程序错误;
2、当传入的argv中的选项全部被解析,getopt()返回-1,这也是getopt进行选项解析的循环截至条件;
3、如果argv中解析出optstring中描述的选项字符,则返回该字符,如果该选项指定了参数,则全局变量optarg指向该参数;
4、如果getopt遇到一个非optstring指定的选项字符,这表示该选项是未识别的,返回'?',并且将该选项存放到全局变量optopt中;
5、如果optstring指定了选项必须带参数,但传入的相应option丢失了参数,返回值依赖于optstring的第一个字符,若第一个字符是':',返回':',否则返回'?';由于非法的选项返回也是'?',所以常常optstring的第一个字符指定为':';同时将该选项存放到全局变量 optopt中;
 
测试例程:
 
 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h> int main(int argc, char *argv[])
{
extern char *optarg;
extern int optind, opterr, optopt;
int i;
int ret; for (i=; i<argc; i++)
{
printf ("argv[%d] %s\n", i, argv[i]);
}
printf ("\n"); while ((ret = getopt(argc, argv, ":a:b::c")) != -)
{
switch (ret) {
case 'a':
printf ("option: %c argv: %s\n", ret, optarg);
break;
case 'b':
if (optarg)
printf ("option: %c argv: %s\n", ret, optarg);
else
printf ("option: %c no argument\n", ret);
break;
case '?':
printf ("encountered a unrecognized option: %c, argv: %s\n", optopt, argv[optind - ]);
break;
case ':':
printf ("option: %c missing argument\n", optopt);
break;
default:
printf ("option: %c\n", ret);
break;
}
} printf ("\noptind: %d\n\n", optind);
for (i=optind; i> && i<argc; i++)
printf ("argv[%d] %s\n", i, argv[i]); printf ("\n");
for (i=; i<argc; i++)
printf ("argv[%d] %s\n", i, argv[i]); return ;
}
然后我们运行测试例程,自己根据前面的描述进行一些分析:
 
root@ParseCmdLine:./parse_cmdline -axxx -byyy
argv[0] ./parse_cmdline
argv[1] -axxx
argv[2] -byyy
 
option: a argv: xxx
option: b argv: yyy
 
optind: 3
 
 
argv[0] ./parse_cmdline
argv[1] -axxx
argv[2] -byyy
 
root@ParseCmdLine:./parse_cmdline -a xxx -b yyy
argv[0] ./parse_cmdline
argv[1] -a
argv[2] xxx
argv[3] -b
argv[4] yyy
 
option: a argv: xxx
option: b no argument
 
optind: 4
 
argv[4] yyy
 
argv[0] ./parse_cmdline
argv[1] -a
argv[2] xxx
argv[3] -b
argv[4] yyy
从这个可以看出,带参数的option参数可以紧跟,也可以中间有空格;
 
root@ParseCmdLine:./parse_cmdline -axxx -b yyy -c
argv[0] ./parse_cmdline
argv[1] -axxx
argv[2] -b
argv[3] yyy
argv[4] -c
 
option: a argv: xxx
option: b no argument
option: c
 
optind: 4
 
argv[4] yyy
 
argv[0] ./parse_cmdline
argv[1] -axxx
argv[2] -b
argv[3] -c
argv[4] yyy
 
root@ParseCmdLine:./parse_cmdline -axxx -byyy -c
argv[0] ./parse_cmdline
argv[1] -axxx
argv[2] -byyy
argv[3] -c
 
option: a argv: xxx
option: b argv: yyy
option: c
 
optind: 4
 
 
argv[0] ./parse_cmdline
argv[1] -axxx
argv[2] -byyy
argv[3] -c
从这里可以看出,对于-b是可跟参数也可不跟参数的,参数必须紧跟,中间不能有空格。同时还可以看出:在有argument在argv中,最后出现了argv[]元素位置变化,选项前移了,而参数后移
 
root@ParseCmdLine:./parse_cmdline -x
argv[0] ./parse_cmdline
argv[1] -x
 
encountered a unrecognized option: x, argv: -x
 
optind: 2
 
 
argv[0] ./parse_cmdline
argv[1] -x
 
root@ParseCmdLine:./parse_cmdline -a
argv[0] ./parse_cmdline
argv[1] -a
 
option: a missing argument
 
optind: 2
 
 
argv[0] ./parse_cmdline
argv[1] -a
这里可以看出未识别的option,和丢失参数的option情况;
 
// 修改代码while ((ret = getopt(argc, argv, "a:b::c")) != -1)
root@ParseCmdLine:./parse_cmdline -x                   
argv[0] ./parse_cmdline
argv[1] -x
 
./parse_cmdline: invalid option -- x
encountered a unrecognized option: x, argv: -x
 
optind: 2
 
 
argv[0] ./parse_cmdline
argv[1] -x
 
// 修改代码while ((ret = getopt(argc, argv, "+a:b::c")) != -1)
root@ParseCmdLine:./parse_cmdline -x xxxx -ayyyy -bzzz kkkk
argv[0] ./parse_cmdline
argv[1] -x
argv[2] xxxx
argv[3] -ayyyy
argv[4] -bzzz
argv[5] kkkk
 
./parse_cmdline: invalid option -- x
encountered a unrecognized option: x, argv: -x
option: a argv: yyyy
option: b argv: zzz
 
optind: 4
 
argv[4] xxxx
argv[5] kkkk
 
argv[0] ./parse_cmdline
argv[1] -x
argv[2] -ayyyy
argv[3] -bzzz
argv[4] xxxx
argv[5] kkkk
这块代码说明了optstring第一个字符的作用,剩余的其他功能读者自己分析;

getopt函数的更多相关文章

  1. getopt函数的使用——分析命令行参数

    getopt(分析命令行参数) getopt(分析命令行参数) 短参数的定义 返回值 范例 getopt_long 相关函数表头文件#include<unistd.h> 函数声明int g ...

  2. Linux c 下使用getopt()函数

    命令行参数解析函数 —— getopt() getopt()函数声明如下: #include <unistd.h> int getopt(int argc, char * const ar ...

  3. Linux下getopt()函数的简单使用

    最近在弄Linux C编程,本科的时候没好好学啊,希望学弟学妹们引以为鉴. 好了,虽然啰嗦了点,但确实是忠告.步入正题: 我们的主角----getopt()函数. 英雄不问出处,getopt()函数的 ...

  4. C语言-getopt函数

    #include<unistd.h> int getopt(int argc,char *const argv[],const char *optstring); extern char ...

  5. 如何使用getopt()函数解析参数

    最近在写程序的过程中,把一部分时间都花费在程序对参数的处理上.今天听了学长说到getopt函数,才发现原来c里面还有一个专门解决参数处理的函数,查询了相关资料,这里简单总结一下. 使用int main ...

  6. liunx 系统调用 getopt() 函数

    命令行参数解析函数 -- getopt() getopt()函数声明如下: #include <unistd.h>int getopt(int argc, char * const arg ...

  7. Python中getopt()函数的使用

    在运行程序时,可能需要根据不同的条件,输入不同的命令行选项来实现不同的功能.目前有短选项和长选项两种格式.短选项格式为"-"加上单个字母选项:长选项为"--"加 ...

  8. [转载]Linux下getopt()函数的简单使用

    转载源地址:https://www.cnblogs.com/qingergege/p/5914218.html 1.getopt()函数的出处就是unistd.h头文件(哈哈),写代码的时候千万不要忘 ...

  9. Linux getopt()函数 getopt_long()函数---转

    http://hi.baidu.com/scoundrelgg/item/d4083f8412eea05d26ebd97f Linux getopt()函数 getopt_long()函数 get_o ...

  10. linux之getopt 函数(转)

    命令行参数解析函数 —— getopt() getopt()函数声明如下: #include <unistd.h> int getopt(int argc, char * const ar ...

随机推荐

  1. GDI 画笔(9)

    使用现有画笔 Windows 提供三种备用画笔(Stock Pen):BLACK_PEN(黑色画笔).WHITE_PEN(白色画笔).NULL_PEN(不绘制任何图形的画笔). 调用 GetStock ...

  2. 洛谷 P1595 信封问题

    题目描述 某人写了n封信和n个信封,如果所有的信都装错了信封.求所有信都装错信封共有多少种不同情况. 输入输出格式 输入格式: 一个信封数n 输出格式: 一个整数,代表有多少种情况. 输入输出样例 输 ...

  3. mysql 与elasticsearch实时同步常用插件及优缺点对比(ES与关系型数据库同步)

    前言: 目前mysql与elasticsearch常用的同步机制大多是基于插件实现的,常用的插件包括:elasticsearch-jdbc, elasticsearch-river-MySQL , g ...

  4. POJ 2079

    呃,不知道我用的算不算卡壳,总有点枚举的意思. 先求凸包,然后,枚举其中一点,再枚举另一点作为结尾,这个向量旋转一周后,求出最大值面积.这里面用的是旋转卡壳判断的那个式子. PS:下一篇和这题是一样题 ...

  5. JS经常使用表单验证总结

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  6. WndProc函数参数列表

    protected override void WndProc(ref Message m) 实现了这一点. 重写WndProc函数,可以捕捉所有窗口发生的消息.这样,我们就可以"篡改&qu ...

  7. oc15--文档安装

    // // main.m // 修改项目模板 /* 工程名称: 文件名称: 创建者 : 创建时间: 版权 : 修改人 : 修改时间: */ #import <Foundation/Foundat ...

  8. nyoj--744--蚂蚁的难题(一)

    蚂蚁的难题(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 小蚂蚁童鞋最近迷上了位运算,他感觉位运算非常神奇.不过他最近遇到了一个难题: 给定一个区间[a,b],在 ...

  9. 框架-Java:Spring MVC

    ylbtech-框架-Java:Spring MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 We ...

  10. libhiredis.so.0.13 => not found 缺少

    wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz tar -xzvf v0.13.3.tar.gz cd hiredis- ma ...