公司网站选择什么空间,秦皇岛高端网站设计,cpa推广联盟,wordpress 显示页码前言#xff1a;最近在学习面向Linux系统进行C语言的编程#xff0c;通过查询man手册和查看网络上的各种文章来获取一点点的知识#xff0c;重点是看完手册还是一脸懵逼#xff0c;搞不懂手册里面再说啥#xff0c;而本篇文章将记录一下学习getopt_long的那些参数和返回值…前言最近在学习面向Linux系统进行C语言的编程通过查询man手册和查看网络上的各种文章来获取一点点的知识重点是看完手册还是一脸懵逼搞不懂手册里面再说啥而本篇文章将记录一下学习getopt_long的那些参数和返回值希望能和大家讲清楚和说明白。
optstring分为三种选项 普通的必须选项(:)可选选项(::)这个略可以自行百度。
0. 可选选项
optstring 为 :a::b:X
Option syntaxMeaning -aOK, No argument provided (optional). -afooOK, argument is foo -a fooWrong, no space allowed with optional arguments. foo is considered a non-option argument. -bfooOK, argument is foo (required). -b fooOK, argument is foo (required). -bWrong, option b requires an argument.
注意可选参数需要紧紧挨着写不能有空格。
1. 未知的选项和缺少选项参数(Unknown Options and Missing Option Arguments)
当我们面对上面两个情况时候如何进行处理
optstring为 a:b:X
当我们输入 -t 时候会出现 未知的选项的错误
当我们输入 -a 而不输入选项参数时候会出现缺少选项参数的错误
一般情况下getopt会输出错误但是我们希望我们能有相关的语句去处理或自定义提示。
我们通过在 optstring前面添加 :即 :a:b:X来进行解决代码如下所示
/* Notice the leading : in the option string */ optwhile ((opt getopt(argc, argv, :a:b:X)) ! -1)
{switch (opt) {case a:printf(Option a has arg: %s\n, optarg);break;case b:printf(Option b has arg: %s\n, optarg);break;case X:printf(Option X was provided\n);break;case ?:printf(Unknown option: %c\n, optopt);break;case ::printf(Missing arg for %c\n, optopt);break;}
}
假设这个程序输出为a.out, 则测试结果为
Command line optionsOutput ./a.out -aMissing arg for a./a.out -tUnknown option: t./a.out -a one -t -X -bOption a has arg: one
Unknown option: t
Option X was provided
Missing arg for b./a.out -a one,two,threeOption a has arg: one,two,three./a.out -a one two threeOption a has arg: one two three
我们查看文档 man 3 getopt 有如下文字与咱们测试结果一致 是说以:开头的话getopt不会打印错误同时针对 缺少选项参数的情况会返回 : 这样可以让调用者或开发者区分这两种情况。通过添加:将getopt关闭打印错误输出。
2. nonoption是否有序及获取相关值
nonoption换一种写法 non-option也行意思是非选项参数。
比如我们执行gcc程序如下所示
gcc -Wall -Wextra main.c foo.c bar.c -O -o program -ansi -pedantic -Werror哪个是non-option其实就是前面没有-和--的也就是 main.c/foo.c/bar.c 而 program是-o选项的参数它不是nonoption。
我们先试一下
#include stdio.h /* printf */
#include getopt.h /* getopt */int main(int argc, char *argv[])
{int opt;while ((opt getopt(argc, argv, :a:b:X)) ! -1) {switch (opt) {case a:printf(Option a has arg: %s\n, optarg);break;case b:printf(Option b has arg: %s\n, optarg);break;case X:printf(Option X was provided\n);break;case ?:printf(Unknown option: %c\n, optopt);break;case ::printf(Missing arg for %c\n, optopt);break;}}/* Get all of the non-option arguments */if (optind argc) {printf(Non-option args: );while (optind argc)printf(%s , argv[optind]);printf(\n);}return 0;
}
测试结果为
Command line optionsOutput ./a.out x -a one y -X zOption a has arg: one
Option X was provided
Non-option args: x y z ./a.out x y z -a one -b twoOption a has arg: one
Option b has arg: two
Non-option args: x y z
我们发现了一个奇怪的现象就是这些非选项参数即使写在了其他选项参数的前面但是它输出在了最后面也就是说并没有按照书写的顺序进行输出。
原因是getopt函数会将这些非选项参数放到数组argv的最后当没有选项处理则返回-1并终止while循环。我们通过optind进行循环来获取后续的参数。
如果你想获取这些 非选项参数并且是按顺序进行输出你需要在optstring前加-通过添加-来关闭getopt将non option移动到argv数组末尾。
#include stdio.h /* printf */
#include getopt.h /* getopt */int main(int argc, char *argv[])
{int opt;/* Notice the leading minus sign - in the option string below */ /* Remember that the number one in single quotes 1 is not the */ /* same as the number one without quotes. 1 is ASCII 49 */ while ((opt getopt(argc, argv, -:a:b:X)) ! -1) {switch (opt) {case a:printf(Option a has arg: %s\n, optarg);break;case b:printf(Option b has arg: %s\n, optarg);break;case X:printf(Option X was provided\n);break;case ?:printf(Unknown option: %c\n, optopt);break;case ::printf(Missing arg for %c\n, optopt);break;case 1:printf(Non-option arg: %s\n, optarg);break;}}return 0;
}
当存在 non option出现时候getopt_long函数返回值为 1
测试结果为
Command line optionsOutput./a.out x y z -a foo Non-option arg: x Non-option arg: y Non-option arg: z Option a has arg: foo ./a.out x -a foo y -b bar z -X w Non-option arg: x Option a has arg: foo Non-option arg: y Option b has arg: bar Non-option arg: z Option X was provided Non-option arg: w ./a.out -t x -a foo -M y -b bar z -X w -b Unknown option: t
Non-option arg: x
Option a has arg: foo
Unknown option: M
Non-option arg: y
Option b has arg: bar
Non-option arg: z
Option X was provided
Non-option arg: w
Missing arg for b 3.长选项以及短选项和长选项的关联
短选项的缺点是
1. 选项个数受限对于小程序这个倒没事但是对于一个复杂的程序就显着不足
2. 无法记住短选项的意思比如 -a代表add但是无法代表alter等
看一下rsync和wget你就会发现有很多的参数而 getopt_long就是处理长选项的函数。
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
argc 代表参数的个数
argv 代表保存各个参数的数组每个参数是一个字符串
optstring 代表短选项的字符串
longopts 代表长选项的配置数组指针
longindex 代表 longopts数组的索引的指针
struct option
{const char *name; /* name without -- in front */int has_arg; /* one of: no_argument, required_argument, optional_argument */int *flag; /* how the results are returned */int val; /* the value to return or to put in flag */
};static struct option long_options[] {{add, required_argument, NULL, 0 },{append, no_argument, NULL, 0 },{delete, required_argument, NULL, 0 },{verbose, no_argument, NULL, 0 },{create, required_argument, NULL, 0 },{file, optional_argument, NULL, 0 },{NULL, 0, NULL, 0 }};
如果flag为NULL则这个 getopt_long函数返回 val
如果flag为指针则将val放到flag指针中这个getopt_long函数返回 0
测试程序如下
#include getopt.h /* getopt */
#include stdlib.h /* exit */
#include stdio.h /* printf */int main(int argc, char **argv)
{int c;while (1) {int option_index 0;static struct option long_options[] {{add, required_argument, NULL, a},{append, no_argument, NULL, p},{delete, required_argument, NULL, d},{verbose, no_argument, NULL, v},{create, required_argument, NULL, c},{file, optional_argument, NULL, f},{NULL, 0, NULL, 0}};/* Still need to provide an option string for the short options */c getopt_long(argc, argv, -:a:pd:vc:f::, long_options, option_index);if (c -1)break;switch (c) {case 0:printf(long option %s, long_options[option_index].name);if (optarg)printf( with arg %s, optarg);printf(\n);break;case 1:printf(regular argument %s\n, optarg);break;case a:printf(option a with value %s\n, optarg);break;case p:printf(option p\n);break;case d:printf(option d with value %s\n, optarg);break;case v:printf(option v\n);break;case c:printf(option c with value %s\n, optarg);break;case f:printf(option f with value %s\n, optarg ? optarg : NULL);break;case ?:printf(Unknown option %c\n, optopt);break;case ::printf(Missing option for %c\n, optopt);break;default:printf(?? getopt returned character code %c ??\n, c);}
}
测试结果为
Command lineOutput ./a.out --deletefoo -c5 --addyes --appendoption d with value foo
option c with value 5
option a with value yes
option p./a.out --dfoo --adyes --apoption d with value foo
option a with value yes
option p./a.out --create5 --create 6 --c7 --c 8 option c with value 5
option c with value 6
option c with value 7
option c with value 8./a.out --file5 --file 6 --file7option f with value 5
option f with value NULL
regular argument 6
Unknown option --d能匹配上--delete--ad能匹配上--add--ap能匹配上--append--c能匹配上--create 4. 传true或false
有些时候的选项并不进行传值而是传true或false
gcc -c foo.c // -c 就是一个flag代表true只编译不链接。如果不写则进行编译和链接。
#include getopt.h /* getopt */
#include stdio.h /* printf *//* File scope flags, all default to 0 */
static int f_add;
static int f_append;
static int f_create;
static int f_delete;
static int f_verbose;int main(int argc, char **argv)
{int c;while (1) {int option_index 0;static struct option long_options[] {{add, no_argument, f_add, 1},{append, no_argument, f_append, 1},{create, no_argument, f_create, 1},{delete, no_argument, f_delete, 1},{verbose, no_argument, f_verbose, 1},{NULL, 0, NULL, 0}};c getopt_long(argc, argv, -:, long_options, option_index);printf(the value of c : %d\n,c);if (c -1)break;switch (c) {case 1:printf(non option argument %s\n, optarg);break;case ?:printf(Unknown option %c\n, optopt);break;}}printf( f_add: %i\n, f_add);printf( f_append: %i\n, f_append);printf( f_delete: %i\n, f_delete);printf( f_create: %i\n, f_create);printf(f_verbose: %i\n, f_verbose);return 0;
}
测试结果为 Command lineOutput ./a.out --verbose --createf_add: 0f_append: 0f_delete: 0f_create: 1
f_verbose: 1./a.out --verbose --append --create --add --deletef_add: 1f_append: 1f_delete: 1f_create: 1
f_verbose: 1./a.out --v --c --ap --ad --df_add: 1f_append: 1f_delete: 1f_create: 1
f_verbose: 1./a.out -v -c -d -aUnknown option v
Unknown option c
Unknown option d
Unknown option af_add: 0f_append: 0f_delete: 0f_create: 0
f_verbose: 0如果flag为NULL则这个 getopt_long函数返回 val
如果flag为指针则将val放到flag指针中这个getopt_long函数返回 0 5. 我的小代码
#include stdio.h /* for printf */
#include stdlib.h /* for exit */
#include getopt.hint main(int argc, char *argv[])
{int c;int digit_optind 0;// 默认为0static int f_flag;while (1) {int this_option_optind optind ? optind : 1;int option_index 0;static struct option long_options[] {{add, required_argument, 0, a},{append, no_argument, 0, p},{delete, required_argument, 0, d},{verbose, no_argument, 0, v},{create, required_argument, 0, c},{file, optional_argument, 0, f},{help, no_argument, 0, h},{flag, no_argument, f_flag, 1 },{0, 0, 0, 0 }};c getopt_long(argc, argv, -:a:pd:vc:f::h,long_options, option_index);//printf(the value of c : %d\n,c)if (c -1)break;switch (c) {case 0:printf(%s (true of false),the flag value is %d\n, long_options[option_index].name,f_flag);break;case 1:printf(non option argument %s\n, optarg);break;case a:printf(option a or add with value %s\n, optarg);break;case p:printf(option p or append\n);break;case d:printf(option d or delete with value %s\n, optarg);break;case v:printf(option v or verbose\n);break;case c:printf(option c or create with value %s\n, optarg);break;case f:printf(option f or file with value %s\n, optarg ? optarg : NULL);break;case ?:printf(Unknown option %c\n, optopt);break;case ::printf(Missing option for %c\n, optopt);break;default: printf(Usage: %s [OPTION...] IMAGE [args]\n\n, argv[0]);printf(\t-a,--add add somethings(required argument)\n);printf(\t-p,--append append somethings(no argument)\n);printf(\t-d,--delete delete somethings(required argument)\n);printf(\t-v,--verbose show the verbose(no argument)\n);printf(\t-c,--create create somethings(required argument)\n);printf(\t-f,--file add a file(required argument)\n);printf(\t-h,--help help(no argument)\n);printf(\t--flag flag 0 or 1(no argument)\n);printf(\n);exit(0);}} exit(EXIT_SUCCESS);
}这个代码可以输出帮助信息以及 上述0、1、2、3、4等各种问题的结合版可以参考谢谢。 参考文档
1. Example of Getopt (The GNU C Library)
2. man 3 getopt
3.Meads Guide To getopt