c语言 getopt函数,命令行多参数解析时getopt()函数的使用方法小结

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

在Linux中,用命令行执行可执行文件时,常常涉及到:大量、不同类型、不同形式的 输入参数问题。从简单的说起,现在假设有我们一个用户定义的可执行程序,名为test.sh,它需要3个输入参数,于是我们通过命令行去执行它的时候,往往通过如下的做法:1./test.sh 1 2 3

一. main函数

上面的./test.sh是执行程序,1、2、3是test.sh的输入参数,这些命令项通过传递给程序的main函数进行处理,main函数的一般形式如下:1int (int argc, char *argv[]);

argc是一个整型,argv是一个指针数组,argc记录argv的大小,例如./test.sh 1 2 3将被以如下的方式传递:1

2

3

4

5argc=4;

argv[0]=./test.sh;

argv[1]=1;

argv[2]=2;

argv[3]=3;

二. getopt函数

现在我们考虑更复杂一些的输入要求,还是以test.sh为例,不过这时它的输入参数要更多一些了1./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T

先说说这一行参数表示什么意思,这里的破折号-表示这是一个控制选项,例如-1,在此处1是单字符选项,而-a 4表示带参数的选项,a是该选项的标识符,4是随同该选项一同传入的参数,-Q,与-1一样,Q也是单字符选项,没有随同的输入参数。通过定义不同的选项,我们可以在test.sh中定义丰富的操作完成各种各样的计算任务,但是这个时候main函数可没有办法给你完成上面的解析工作,main函数只是将./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T传递进来,保存在argc和argv里,至于这些参数如何分配并对应什么操作则是需要用户自行定义了,当然,自己写解析函数是可行的,但是有更好的选择。

在C语言中,unistd.h提供的getopt()这个函数,结合switch语句,可以帮助我们方便实现参数解析。

先看例子:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38……

int opt;

while ( (opt=getopt(argc, argv, "123a:b:c:QST")) != -1 )

{

switch (opt)

{

case '1':

para1 = 1;

break;

case '2':

para2 = 2;

break;

case '3':

para3 = 3;

break;

case 'a':

para4 = atof(optarg);

break;

case 'b':

para4 = atof(optarg);

break;

case 'c':

para5 = atof(optarg);

break;

case 'Q':

definedOption1 = true;

break;

case 'S':

definedOption2 = true;

break;

case 'T':

definedOption3 = true;

break;

……

}

……

}

……

getopt()函数原型为:1int getopt(int argc, char * const argv[], const char *optstring);

使用getopt函数需要包含以下头文件:1

2#include

有几个全局变量与getopt函数解析参数有关:

optind:int型, 指示下一个要解析的参数位置,初始时为1。

optarg:char *, 必须接参数的选项元素的参数, optarg 就指向参数字符串。

opterr: int 型, 设为0将不打印错误信。

int argc, char * const argv[]一般是直接通过读取main函数的argc和argv,而optstring则是用户定义的选项字符,例如在上面的例子中,optstring是 123a:b:c:QST ,它用来解析输入参数./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T,并且是由用户定义。

字符串optstring的元素一般可分为下面几种:单个字符,表示选项,123a:b:c:QST中的1、2、3、Q、S、T都是单字符选项

单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后以空格隔开。该参数的指针赋给optarg。123a:b:c:QST中的a:, b:, c: 都表示它们需要附加指定输入参数,这就是为什么在输入参数时是-a 4 -b 5 -c 6的缘故

单个字符后跟两个冒号::表示该选项后可选地跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张,本例中不作介绍)。

:或两个冒号::的组合),不能用多个字符来表示一个选项。

例如这样做就会识别出错:

用户输入的参数./test.sh -1 -2 -3 -a1 4 -b 5 -c 6 -Q -S -T,那么它对应的optstring则是 123a1:b:c:QST,显然其中a1为两个字符,想让它表示一个选项,是会出现问题的。

同时,getopt()在unistd.h中的相关定义:1

2

3

4

5* extern char *optarg; //选项的参数指针

* extern int optind, //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。

* extern int opterr, //当opterr=0时,getopt不向stderr输出错误信息。

* extern int optopt; //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,

//该选项存储在optopt中,getopt返回'?'

那么现在就清楚用户输入的参数./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T是怎么进行传递和解析的了:通过main函数将输入参数./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T保存在argc和argv

getopt()按照123a:b:c:QST这个规则去解析argc和argv中保存的数据

例如,首先去./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T读取到的选项是-1(第一个输入参数./test.sh是执行程序是名称不予考虑),于是就去123a:b:c:QST中检查是否有1这个选项,有的话就返回该选项(这个时候就会转入相应的case执行对应的操作),同时将选项索引optind更新为输入参数的下一个位置(此处为-2的位置)作为下次搜索的开始位置,如果在optstring里没有找到1,例如我们的optstring是23a:b:c:QST,即当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?',并从optind开始进行下一个输入参数的解析

继续解析,当解析到-a时,这个时候getopt()发现optstring里的a后面跟着:于是它知道a是还需要传递进来一个指定的参数,于是就将指针*optarg指向-a后面的一个参数即是4,这样返回选项a的时候,a所对应的参数值此时由optarg指向,这样转入case 'a'的时候就可以对该参数进行相应的操作了1

2

3case 'a':

para4 = atof(optarg);

break;

接着往下走,-Q -S -T与前面的-1是一样的,都是不带参数的单字符选择,当检查完-T后,返回-1,表示检查完毕,这个时候就完成了对./test.sh -1 -2 -3 -a 4 -b 5 -c 6 -Q -S -T中所有参数的分配工作。

上述简单介绍了命令行多参数解析时getopt()函数的用法,若有错误,欢迎斧正与探讨;若干概念引自文献[1],若有需要相关概念更详细的解释,可前往阅读。

三. 实例

在Eureka中进行的FSI数值算例中用到如下控制选项,整理出来作为备忘。1

2

3

4

5

6

7输入

./$1 -2 -L 290 -H 120 -J 0.1 -h 8.0 -D 500 -r 1.5 -c 1.0e-5 -x 3.1 -b 1.6 -q 1 -R 1 -M 0.01

-U -Q -t 0.1 -T 0.1 -d 1000 -v 513 -f 1 -G 1.0e7 -k 1.42e5 -p 1.18e-6 -g 1.4 -m 0 -s 1.82e-5

-i 0.1 -l 10.0 -I 0.0 -A 0.0 -E 2.5e6 -P 1e-4 -N 0.35 -n 8 -K 10.0

解析

getopt(argc, argv, "23L:H:W:J:h:D:r:c:x:b:q:R:M:SQUt:T:d:v:f:G:k:p:g:m:s:i:l:I:A:E:P:N:n:K:");控制符值含义./$1执行程序名称,e.g. verification_oscillation_structure.gcc_v714M.st

-22二维

-33三维

-L290Length

-H120Height

-W0Width

-J0.1critical_shear/maximum shear strain

-h8element size that determines the patch thickness 入口单元尺寸

-D500Domain_End 计算域终点,计算域起点为0.0

-r1.5searchRange, parameters for the shape function

-c1.0e-5cutoff, parameters for the shape function

-x3.1extension, parameters for the shape function

-b1.6beta, parameters for the shape function

-q1integration_order q=1表示单元的中心插入1个质量点

-R1nRing 邻域控制,1表示从单元本身节点开始,如果变形大,可以设置为2

-M0.01mass_factor

-Strueadaptive_search

-Qtrueadaptive_beta

-UtrueupdateNeighbor

-t0.1time step ratio 0.1表示10%

-T0.1total_time simulation time

-d1000dump,number of time steps to visualize the results

-v513max velocity of inflow,speed

-f1.0parameters for the rupture of solids,epsilon_h=1 包含裂纹扩展

-G1.0e7parameters for the rupture of solids

-k1.42e5the bulk modulus of fluid (2.1e9 Pa for water) 体积模量

-p1.18e-6the density of fluid (1.0e3 kg/m^3 for water)

-g1.4Gruneisen parameter in the equation of state of the fluid

-m0nuf,poisson’s ratio of the fluid

-s1.82e-5the shear viscosity coefficient of fluid (1.82e-5kg/(m.s))动力粘度

-i0.1artificial viscosity coefficient to stablize the simulation 经验系数

-l10artificial viscosity coefficient to stablize the simulation 经验系数

-I0.0artificial viscosity coefficient to stablize the simulation 经验系数

-A0.0artificial viscosity coefficient to stablize the simulation 经验系数

-E2.5e6E_Solid,Young’s modulus of solid 固体材料弹性模量

-P1.0e-4rho_Solid,density of solid 固体材料密度

-N0.35nu_Solid,Poisson’s ratio of solid 固体材料泊松比

-n8number of threads 线程数

-K10

四. 参考文献

2016年2月1日16:18:12

于克利夫兰

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言getopt()函数用于分析命令行参数。它的声明为: int getopt(int argc, char * const argv[], const char * optstring); 该函数通过解析命令行参数来获取选项和参数的值。用户可以在命令行使用不同的选项来传递参数给程序。 下面是一个getopt()函数的示例代码: #include <unistd.h> #include <stdio.h> int main(int argc, char * argv[]){ int i; printf("%s\n","argv原序:"); for(i = 0;i < argc;i++){ printf("%s ",argv[i]); } printf("\n"); printf("START@optind:%d,opterr:%d\n",optind,opterr); int ret; while((ret = getopt(argc,argv,"aW;b:c:de::")) != -1){ switch(ret){ case 'a': printf("Having option -a\n"); break; case 'b': printf("having option -b,and its argument is %s\n",optarg); break; case 'c': printf("having option -c,and its argument is %s\n",optarg); break; case 'd': printf("Having option -d\n"); break; case 'e': printf("having option -e,it is optional,and its argument is %s\n",optarg); break; case '?': printf("Unknown option -%c\n",(char)optopt); break; } } printf("END@optind:%d,argv[%d]:%s\n",optind,optind,argv[optind]); printf("%s\n","argv现序:"); for(i = 0;i < argc;i++){ printf("%s ",argv[i]); } printf("\n"); return 0; } 该示例演示了如何使用getopt()函数解析命令行参数。程序通过指定选项和参数的形式来接受用户输入,并根据不同的选项执行不同的操作。在示例,选项包括:a、b、c、d和e,其e选项是可选的。通过在命令行输入相应的选项和参数,程序会根据不同的选项执行相应的代码逻辑。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C语言getopt()函数和select()函数使用方法](https://download.csdn.net/download/weixin_38621104/14868224)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C语言——getopt函数](https://blog.csdn.net/weixin_40763897/article/details/87898328)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值