目录
一、getopt
#include <unistd.h>
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#include <unistd.h>
extern char *optarg;
extern int optind, opterr, optopt;
description:
该函数的作用是:解析命令行的参数。
其中,参数argc和argv是参数的数量和一个数组,是由main函数进行程序调用时传递的;并且,argv中的元素是‘-字符’这种形式的,该字符被称作短选项;如果该函数被反复的调用,则它将会从选项元素(argv数组中的元素)中先后的返回每一个选项字符(-后面的字符)。
optstring:
它是由合法选项字符组成的字符串,如果字符后面带有冒号(:),则这个选项需要一个参数,所以在相同的argv元素中,该函数会放置一个指针到接下来的文本。两个冒号意味着一个选项带着一个可选的参数,如果在当前的argv元素中保存的是一个文本(例如-oarg),则该文本会被返回在optarg中,否则optarg会设置成0,这是GNU的一个外延。
如果optstring包含W后接一个分号(;),则-W foo被称作长选项。
我们注意到,该函数可以导出三个参数:optind,opterr,optopt。
对于optind:
变量optind是在argv中下一个要处理的参数的索引。系统会初始化这个值为1,调用者可以重置它为1来重新扫描相同的argv,或者当扫描一个新的参数向量的时候将它重置为1 。如果该函数发现另一个选项字符,它将返回这个字符。并且更新外部的变量optind和一个静态的变量nextchar,因此,下一次调用该函数可用接着的字符或者argv元素来重新扫描 。如果没有更多的选项字符,函数会返回-1,同时optind会是在argv中第一个argv元素的下标,但是该下标不会指向一个选项 。
对于stderr:
如果该函数不识别一个选项字符,则会打印一个错误的消息到stderr中,并且保存该字符到optopt中,且返回‘?’,调用程序可以通过将opterr设置到0来预防该错误信息。
对于optopt:
如果该函数发现argv中的一个选项字符不包含在optstring中,或者如果该函数察觉到一个缺失的选项参数,该函数返回‘?’,并且设置外部的变量optopt为真实的选项字符。如果opstring中的第一个字符是冒号(:),则该函数返回“:”来代替“?”,来表明一个确实的选项参数。如果一个错误被检测到,并且optstring中的第一个参数不是冒号(:),同时外部的变量opterr是一个非零值,则该函数会打印一个错误信息。
默认情况:
默认情况下,当该函数扫描的时候会改变argv的内容,所以最终所有的非选项都在最后。两种其他的模式也会被执行。如果optstring的第一个字符是‘+’或者optstring的环境变量是POSIXLY_CORRECT,则一旦遇上非选项字符就会停止处理选项。如果它的第一个字符是‘-’,则每一个非选项argv元素会被处理,似乎它是字符编码为1的选项参数。
二、 getopt_option_only
#include <getopt.h>
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
:_GNU_SOURCE
#include <unistd.h>
extern char *optarg;
extern int optind, opterr, optopt;
该函数几乎同getopt一样,除了该函数也可以接受长选项,开始于两个破折号。(如果程只接受长选项,则optstring应该被指定一个无内容的字符串:“”,而不是一个空的字符串)。长选项可以带
一个参数,形式是:--arg=param或者--arg param。
longopts:是一个指向一个结构体数组struct option (该结构体被定义在getopt.h中)的第一个元素。该结构体原型如下:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
name:长选项的名字
has_arg:
无参数:no_argument(0),如果该选项不带参数
需要参数:required_argument(1),如果选项需要一个参数
可选的参数:optional_argument(2),如果选项带一个可选的参数。
flag:
为长选项指定一个返回值。如果flag是NULL,则该函数返回val,否则该函数返回0,并且flag指向一个被设置到val的变量如果选项是发现的,但是左边不改变,当选项找不到时。
val:
是一个返回值,或者通过flag加载到变量的指针。
在argv中的最后一个元素不得不被设置为0;
longindex:不是空的,它指向一个被设置成长选项的下标的变量
三、返回值
如果一个选项被成功的发现,则getopt()函数返回这个选项字符。如果全部的命令行选项被解析完毕,getopt()返回-1;如果getopt()遇到一个不在optstring中的选项字符,则返回‘?’,如果getopt()遇到一个带有缺失参数的选项,则返回值取决于第一个在optstring中的第一个字符,如果optstring中第一个字符与是‘:’,则‘:’会被返回,否则返回‘?’。
getopt_option_only()返回选项字符,当一个短选项被识别出的时候。对于一个长选项,则返回val的值,当flag为NUILL的时候;当flag为0的则不会返回val的值。对于错误和-1的返回情况,该函数和getopt相同。另外,当一个模糊不清的匹配或者一个外部的参数的时候,也返回‘?’。
四、环境变量
POSIXLY_CORRECT:如果该环境变量被设置,则选项处理会立即停止,当遇到一个非选项参数的时候。
五、例子:
5.1:对于getopt:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
int flags,opt;
int nsecs,tfnd;
nsecs = 0;
tfnd = 0;
flags = 0;
while ((opt = getopt(argc, argv, "nt:")) != -1) {
switch (opt) {
case 'n':
flags = 1;
break;
case 't':
nsecs = atoi(optarg);
tfnd = 1;
break;
default: /* '?' */
fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
argv[0]);
exit(EXIT_FAILURE);
}
}
printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\n",
flags, tfnd, nsecs, optind);
if (optind >= argc) {
fprintf(stderr, "Expected argument after options\n");
exit(EXIT_FAILURE);
}
printf("name argument = %s\n", argv[optind]);
/* Other code omitted */
exit(EXIT_SUCCESS);
}
5.2:getopt_option_only
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>
int
main(int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"delete", required_argument, 0, 0 },
{"verbose", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 0 },
{0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
case 'a':
printf("option a\n");
break;
case 'b':
printf("option b\n");
break;
case 'c':
printf("option c with value '%s'\n", optarg);
break;
case 'd':
printf("option d with value '%s'\n", optarg);
break;
case '?':
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}
exit(EXIT_SUCCESS);
}