int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
函数说明:
函数用于解析命令,选项,参数
cmd -option arg
‘-’之后为选项,选项之后可能为参数。
argc,argv用于传输命令信息。
optstring 用于指定选项列表,有两种指定方式
optstring = "xp"
optstring = "x:p:"
前者表示选项有x,p,且不带参数,后者表示选项有x、p,且都带有参数。
在使用后者optstring时,选项之后的单词被当成参数,如:
a.out -x -p
这里 "-p"被当成-x的参数。
函数返回 int 类型,成功时返回检查到的选项字符,失败时返回-1(表示传输信息检查完毕且未发现选项)。
通过反复调用该函数,直到返回-1,以处理传输信息的所有选项。
全局变量:
optarg,当找到选项后,optarg会被指向该选项的参数。
optind,初始化为 1,表示将要被检查的输入信息的索引,当找到选项后,optind 后移,具体如下:
//当 optstring = "x:p",即选项带参数
./a.out -x 123 -p
上面的情况,一次调用 getopt,找到 x 选项,optind 被后移,由 optind == 1 改变为 optind == 3
//当 optstring = "xp" 即不带参数
./a.out -x -p
上面情况,一次调用 getopt ,找到 x 选项,optind 被后移,由 optind == 1 改变为 optind == 2
可以看出 ,optind 是 argv 的数组索引,指向下一个被期望为选项的位置。
opterr用于禁止显示由getopt()打印的错误信息,该变量默认为1,可以设置为0,以禁止打印错误信息。
optopt用于指向出错时的信息,如
//optstring = "x:p:"
./a.out -x
-x之后需要参数,但是没有,那么 optopt 就存放了字符 'x'
//optstring = "xp"
./a.out a
'a'不是选项字符,optopt存放该错误字符。
返回值:
正常情况,getopt返回找到的选项字符。
如果输入选项(这种格式:-a)不是optstring中选项字符,则返回 '?',若输入为 a(非-a),不会返回'?'
如果选项字符带参数,但是没有输入参数,则返回 ':'
返回 -1 的情况:
(1)argv 遍历完了,即argv[optind] == NULL
(2)argv[optind][0] != '-' 即输入选项 x
(3)没有输入正确的选项。
示例程序:
/*************************************************************************\
* Copyright (C) Michael Kerrisk, 2019. *
* *
* This program is free software. You may use, modify, and redistribute it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation, either version 3 or (at your option) any *
* later version. This program is distributed without any warranty. See *
* the file COPYING.gpl-v3 for details. *
\*************************************************************************/
/* Listing B-1 */
#include <ctype.h>
#include "tlpi_hdr.h"
#define printable(ch) (isprint((unsigned char) ch) ? ch : '#')
static void /* Print "usage" message and exit */
usageError(char *progName, char *msg, int opt)
{
if (msg != NULL && opt != 0)
fprintf(stderr, "%s (-%c)\n", msg, printable(opt));
fprintf(stderr, "Usage: %s [-p arg] [-x]\n", progName);
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
int opt, xfnd;
char *pstr;
xfnd = 0;
pstr = NULL;
while ((opt = getopt(argc, argv, ":p:x")) != -1) {
printf("opt =%3d (%c); optind = %d", opt, printable(opt), optind);
if (opt == '?' || opt == ':')
printf("; optopt =%3d (%c)", optopt, printable(optopt));
printf("\n");
switch (opt) {
case 'p': pstr = optarg; break;
case 'x': xfnd++; break;
case ':': usageError(argv[0], "Missing argument", optopt);
case '?': usageError(argv[0], "Unrecognized option", optopt);
default: fatal("Unexpected case in switch()");
}
}
if (xfnd != 0)
printf("-x was specified (count=%d)\n", xfnd);
if (pstr != NULL)
printf("-p was specified with the value \"%s\"\n", pstr);
if (optind < argc)
printf("First nonoption argument is \"%s\" at argv[%d]\n",
argv[optind], optind);
exit(EXIT_SUCCESS);
}