getopt() 与getopt_long()
Linux命令行选项处理
--------------------------------------------------------------------------------
常用格式:
commandname [-options] [arg1 [arg2 [...argn]]]
多个选项:
ex: ls -l -u b*
组合:
ex: ls -lu b*
带参数选项:
ex: gcc -c -Wall prog.c
--------------------------------------------------------------------------------
getopt()函数
#include <unistd.h>
int getopt(int argc,char *const *argv,const char *optstring);
extern char *optarg; /* Ptr to option argument */
extern int optind; /* argv[] index */
extern int opterr; /* Controls error processing */
--------------------------------------------------------------------------------
1.指针 optarg 指向[正在处理]的的[选项的参数]
比如getopt()在处理选项-Wall或-W all
[调用返回后]optarg指向[C字符串]all
<为什么世界上有那么多的字符串类型啊>
2.变量optind[初始化值为1]。
getopt()将optind的数值置为
将要使用的下一个argv[]数组的下标。
所以当[选项]处理完后,optind为第一个[参数]在argv[]中的下标。
<这个变量的作用很大,可以用来区分[选项]和[参数],这两个概念一定要区分开来>
<实际上,getopt()用来处理[选项]和[选项的参数],对于[参数](独立的参数,不是选项中带的),就要等[选项]处理完用optind来处理了>
<从这里你就可以看出为什么敲命令行时要先敲[选项],再敲[参数]了>
3.变量opterr[初始化为1(表示true)],并作为getopt()函数的一个[输入]。
当opterr为true并且碰到一个不认识字符时
向stderr输出一个消息指出不认识的选项。
当opterr为false并且碰到一个不认识字符时
禁止输出错误消息。
4.返回值 当处理[选项]时,返回处理[选项]的单个字符
当处理完[选项]时,返回-1。接下来可以利用optind处理[参数]
5.函数原型中的参数 argc,argv意义就很明显了。optstring用来给出你需要处理的选项
例如以gcc的三个选项为例:
static char optstring[]="cgW:";
c对应 -c
g对应 -g
W:对应 -W <warninglevel>
其中:表示选项带参数。
getopt()返回的字符就是optstring里面有的,否则会发出错误信息,返回'?'
#include 〈stdio.h〉
#include 〈unstd.h〉
int main( int argc, char ** argv) {
int optch;
static char optstring[] = "gW:c";
while ( ( optch = getopt(argc,argv,optstring) ) != -1 )
switch ( optch ) {
case 'c':
puts("-c processed.");
break;
case 'g':
puts("-g processed.");
break;
case 'W':
printf("-W '%s'processed.",optarg);
break;
default:
puts("Unknown Option!");
}
//处理完选项,下边处理参数
for(;optind< argc;++optind)
printf("argv[%d] = '%s' /n",optind,argv[optind]);
return 0;
}
---------------------------------------------------------------------------
其实,几乎每一个命令都用getopt()处理参数,才使得我们的界面如此相似。
不信?你随便找个命令的elf格式文件,用一下 nm -D 〈程序〉看看里面是不是有getopt?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
getopt_long()
分析命令行选项是一件繁琐的工作。幸运的是GNU C库提供了一个函数使你在处理这项工作时能简单一点。这个函数是getopt_long,它能理解长短两种选项。如果你使用这个函数要包含头文件.
假设你要写一个接受三个选项的程序,参数如下:
-h/--help 显示程序用法并退出。
-o/--output filename 指定输出文件名。
-v/--verbose 打印版本信息。
此外,程序还接受零或多个附加的用来指出输入文件的命令行参数。
要使用getopt_long,你必须提供两个数据结构。头一个是包含有效短选项的字符串,每个选项一个字符。需要参数的选项后面放一个冒号。比如我们的程序,这个字符串为ho:v,表示有效选项是-h,-o与-v并且第二个参数-o后面需要一个参数。
要 指定可用的长选项,你要构建一个option结构的数组。每个元素对应一个长选项,并有四个域。一般情况下,第一个域是长选项的名字(一个字符串,不包含 两个连字符),第二个域如果是1表示这个选项接受一个参数,如果为0表示没有参数。第三个是NULL,第四个是一个字符常量指出与这个长选项对应的短选 项。最后的数组元素全部域应该都为0.对于我们的程序这个结构数组应为:
const struct option long_options[] =
{
{ help , 0, NULL, h },
{ output , 1, NULL, o },
{ verbose , 0, NULL, v },
{ NULL, 0, NULL, 0 }
};
调用getopt_long时,向它传递main的参数argc,argv,描述短选项的字符串与描述长选项的option结构数组。
*每调用getopt_long一次,它分析一个选项,返回这个选项的短选项字母,如果没有发现选项则返回-1.
*典型情况下,我们在一个循环中调用getopt_long,来处理所有用户指定的选项,并通过一个switch语句来处理特别的选项。
*如果getopt_long遇到一个无效选项,它将打印一个错误信息并返回字符'?'。大多数程序将因此退出,并显示用法提示。
*在处理需要参数的选项时,全局变量optarg指向这个参数正文。
*当getopt_long完全全部选项分析时,全局变量optind包含第一个非选项参数在argv中的索引。
下面是使用getopt_long处理选项的完整例子:
#include
#include
#include
/* The name of this program. */
const char* program_name;
/* Prints usage information for this program to STREAM (typically
stdout or stderr), and exit the program with EXIT_CODE. Does not
return. */
void print_usage (FILE* stream, int exit_code)
{
fprintf (stream, "Usage: %s options [ inputfile ... ]/n", program_name);
fprintf (stream,
" -h --help Display this usage information./n"
" -o --output filename Write output to file./n"
" -v --verbose Print verbose messages./n");
exit (exit_code);
}
/* Main program entry point. ARGC conains number of argument list
elements; ARGV is an array of pointers to them. */
int main (int argc, char* argv[])
{
int next_option;
/* A string listing valid short options letters. */
const char* const short_options = "ho:v";
/* An array describing valid long options. */
const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "output", 1, NULL, 'o' },
{ "verbose", 0, NULL, 'v' },
{ NULL, 0, NULL, 0 } /* Required at end of array. */
};
/* The name of the file to receive program output, or NULL for
standard output. */
const char* output_filename = NULL;
/* Whether to display verbose messages. */
int verbose = 0;
/* Remember the name of the program, to incorporate in messages.
The name is stored in argv[0]. */
program_name = argv[0];
do {
next_option = getopt_long (argc, argv, short_options,
long_options, NULL);
switch (next_option)
{
case 'h': /* -h or --help */
/* User has requested usage information. Print it to standard
output, and exit with exit code zero (normal termination). */
print_usage (stdout, 0);
case 'o': /* -o or --output */
/* This option takes an argument, the name of the output file. */
output_filename = optarg;
break;
case 'v': /* -v or --verbose */
verbose = 1;
break;
case '?': /* The user specified an invalid option. */
/* Print usage information to standard error, and exit with exit
code one (indicating abonormal termination). */
print_usage (stderr, 1);
case -1: /* Done with options. */
break;
default: /* Something else: unexpected. */
abort ();
}
}
while (next_option != -1);
/* Done with options. OPTIND points to first non-option argument.
For demonstration purposes, print them if the verbose option was
specified. */
if (verbose) {
int i;
for (i = optind; i < argc; ++i)
printf ("Argument: %s/n", argv[i]);
}
/* The main program goes here. */
return 0;
}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Getopt()
getopt在UNIX下的命令列程式特别好用,特别是在你有许多参数要加入时。一般来说,你可以透过「 man 3 getopt」来获得其说明。这个函数很好用,也很简单,但网上关于这个函数的中文介绍实在是少之又少,这篇文章就简单讲述一下如何利用getopt函数来获取参数,希望能给那些被参数读取弄得有一点点烦躁的朋友有一点点帮助。
1、函数说明
n 表头文件:#i nclude <unistd.h>
n 函数声明:int getopt(int argc, char * const argv[], const char *optstring);
n 函数说明:getopt()用来分析命令行参数。参数argc和argv是由main()传递的参数个数和内容。参数optstring 则代表欲处理的选项字符串。此函数会返回在argv 中下一个的选项字母,此字母会对应参数optstring 中的字母。如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。如果getopt()找不到符合的参数则会印出错信息,并将全域变量optopt设为“?”字符,如果不希望getopt()印出错 信息,则只要将全域变量opterr设为0即可。
n 返回值:如果找到符合的参数则返回此参数字母,如果参数不包含在参数optstring 的选项字母则返回“?”字符,分析结束则返回-1。
2、例子程序
下面是一个使用getopt函数读取参数的例子程序,该程序支持 –p –s –b –c的参数,并将这些参数值读取后进行打印。你可以根据需要将这些代码稍作修改用于自己的程序中。
/*
* getopt.c
* Author: Coonxu
* email: coonxu@126.com
* 这是一个使用getopt函数读取参数的例子程序,该程序支持 -p -s -b -c的参数,
* 并将这些参数值读取后进行打印。你可以根据需要将这些代码稍作修改用于自己的程序中。
*/
#i nclude <unistd.h>
#i nclude <stdio.h>
int main(int argc, char **argv)
{
int ch;
opterr = 0;
while( ( ch = getopt( argc, argv, "s:b:c:p:" ) ) != EOF )
{
switch(ch)
{
case 's':
printf("s opt: %s/n", optarg);
break;
case 'b':
printf("b opt: %s/n", optarg);
break;
case 'c':
printf("c opt: %s/n", optarg);
break;
case 'p':
printf("p opt: %s/n", optarg);
break;
case '?':
printf( "illegal option: %c/n", ch );
break;
}
}
return 0;
}