getopt函数用法详解
getopt函数简介
- 头文件包含
#include <unistd.h>
#include <getopt.h>
- 函数定义
int getopt(int argc , char * const argv[] ,
const char * optstring );
extern char * optarg ;
extern int optind , opterr , optopt ;
int getopt_long(int argc , char * const argv[] ,
const char * optstring ,
const struct option * longopts , int * longindex );
int getopt_long_only(int argc , char * const argv[] ,
const char * optstring ,
const struct option * longopts , int * longindex );
getopt函数常见使用错误
- 编译错误
warning: implicit declaration of function ‘getopt’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <unistd.h>
#include <getopt.h>
getopt函数详细描述
getopt ()函数解析命令行参数。它的参数argc和argv是在程序调用时传递给main ()函数的参数计数和数组。以\(aq-\(aq)开头的argv元素(并不完全是“-”或“--”)是一个option元素。这个元素的字符(除了初始的\(aq-\(aq)之外)是option字符。如果重复调用getopt (),它会从每个option元素中连续返回每个option字符。
变量optind是argv 中要处理的下一个元素的索引,系统将该值初始化为1。调用者可以将其重置为1,以重新扫描同一个argv 或扫描新的参数向量。
如果getopt ()找到另一个选项字符,它将返回该字符,更新外部变量optind和静态变量nextchar,以便对getopt ()的下一次调用可以使用以下选项字符或argv-element继续扫描。
如果没有更多的选项字符,getopt ()返回-1。那么optind是argv中第一个不是选项的PPPP2元素的索引。
optstring是包含合法选项字符的字符串。如果这样的字符后面跟一个冒号,则该选项需要一个参数,因此getopt ()在同一个argv-element中放置一个指向以下文本的指针,或者在optarg 中放置一个指向以下PPPP8-element的文本的指针,两个冒号表示一个选项接受一个可选参数;如果当前PPPP8-element中有文本(即,与选项名称本身在同一个单词中,例如“-oarg”),则在optarg中返回该文本,否则PPPP11被设置为零。这是一个GNU扩展。如果optstring包含后跟分号的 W ,则 -W foo 被视为长选项--foo (POSIX.2为实现扩展保留了 -W 选项)这种行为是GNU扩展,在glibc 2之前的库中不可用。
默认情况下,getopt ()在扫描时会对argv的内容进行置换,因此最终所有非选项都在末尾。还实现了另外两种扫描模式。如果optstring的第一个字符是\(aq+\(aq)或者设置了环境变量 POSIXLY_CORRECT ,那么一旦遇到非option参数,option处理就会停止。如果PPPP3的第一个字符是\(aq-\(aq),那么每个非option pargv元素都被当作字符代码为1的option的参数来处理(这是由那些希望options和其他PPPP2元素以任何顺序排列并关心两者顺序的程序使用的)。特殊参数“--”强制结束option-scanning,而不管扫描模式如何。
在处理选项列表时,getopt ()可以检测两种错误:(1)在optstring中没有指定的选项字符和(2)缺少选项参数(即,命令行末尾的选项没有预期的参数)。此类错误的处理和报告如下:
- 默认情况下,getopt ()在标准错误上打印一条错误消息,将错误的选项字符放入optopt 中,并返回\(aq?\(aq作为函数结果。
- 如果调用方已将全局变量opterr设置为零,则getopt ()不会打印错误消息。调用者可以通过测试函数返回值是否为\(aq?\(aq.(默认情况下,opterr具有非零值)来确定存在错误
- 如果optstring的任何可选\(aq+\(aq或\(aq-\(aq)后面的第一个字符是冒号(\(aq:\(aq),那么getopt ()同样不会打印错误消息。此外,它返回\(aq:\(aq)而不是\(aq?\(aq)以指示缺少的选项参数。这允许调用者区分两种不同类型的错误。getopt_long() and getopt_long_only() getopt_long ()函数的工作方式类似于getopt (),只是它也接受以两个破折号开头的长选项。(如果程序只接受长选项,则optstring应指定为空字符串(“”),而不是NULL。)如果缩写是唯一的或者与某个定义的选项完全匹配,则长选项名称可以缩写。long选项可以采用 --arg=param 或"--arg param" 形式的参数
longopts是指向
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
不同字段的含义是:
- name是long选项的名称。
- has_arg是:no_argument(或0),如果选项不带参数;如果选项需要参数,则为required_argument(或1);如果选项采用可选参数,则为optional_argument(或2)。
- flag指定如何为长选项返回结果。如果flag为空,则getopt_long ()返回val。(例如,调用程序可以将PPPP4设置为等效的短选项字符。)否则,getopt_long ()返回0,PPPP3指向一个变量,如果找到选项,该变量设置为PPPP4,但如果没有找到选项,则保持不变。
- val是要返回或加载到flag所指向的变量中的值。
数组的最后一个元素必须用零填充。
如果longindex不为NULL,则它指向一个变量,该变量被设置为long选项相对于longopts 的索引
getopt_long_only ()类似于getopt_long (),但是\(aq-\(aq)和“--”可以表示长选项。如果以\(aq-\(aq(不是“--”)开头的选项不匹配长选项,但匹配短选项,则它被解析为短选项。
getopt函数返回值
如果成功找到一个选项,那么getopt ()返回选项字符。如果已经解析了所有命令行选项,则getopt ()返回-1。如果getopt ()遇到optstring 中没有的选项字符,则返回\(aq?\(aq)。如果getopt ()遇到缺少参数的选项,则返回值取决于optstring :中的第一个字符,如果它是\(aq:\(aq,则返回\(aq:\(aq);否则返回\(aq?\(aq)。
当识别出短选项时,PPP0和getopt_long_only ()也返回选项字符。对于long选项,如果flag为空,则返回val,否则返回0。Error和-1的返回与getopt ()加\(aq?\(aq)对于不明确的匹配或无关参数的返回相同。
getopt函数其他说明
一个程序扫描多个参数向量,或多次重新扫描同一向量,并希望在optstring 开始时使用GNU扩展,如\(aq+\(aq和\(aq-\(aq),或在两次扫描之间更改 POSIXLY_CORRECT 的值,必须通过将optind重置为0而不是传统的值1来重新初始化getopt ()。(重置为0会强制调用内部初始化例程,该例程会重新检查 POSIXLY_CORRECT 并检查optstring )中的GNU扩展
getopt函数使用举例
getopt()下面这个简单的示例程序使用getopt ()来处理两个程序选项:没有关联值的-n ;和需要关联值的"-t val" 。
#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 \(aqn\(aq:
flags = 1;
break;
case \(aqt\(aq:
nsecs = atoi(optarg);
tfnd = 1;
break;
default: /* \(aq?\(aq */
fprintf(stderr, "Usage: %s [\-t nsecs] [\-n] name\en",
argv[0]);
exit(EXIT_FAILURE);
}
}
printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\en",
flags, tfnd, nsecs, optind);
if (optind >= argc) {
fprintf(stderr, "Expected argument after options\en");
exit(EXIT_FAILURE);
}
printf("name argument = %s\en", argv[optind]);
/* Other code omitted */
exit(EXIT_SUCCESS);
}
getopt_long()下面的示例程序演示了getopt_long ()及其大部分功能的使用。
#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, \(aqc\(aq},
{"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("\en");
break;
case \(aq0\(aq:
case \(aq1\(aq:
case \(aq2\(aq:
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv\-elements.\en");
digit_optind = this_option_optind;
printf("option %c\en", c);
break;
case \(aqa\(aq:
printf("option a\en");
break;
case \(aqb\(aq:
printf("option b\en");
break;
case \(aqc\(aq:
printf("option c with value \(aq%s\(aq\en", optarg);
break;
case \(aqd\(aq:
printf("option d with value \(aq%s\(aq\en", optarg);
break;
case \(aq?\(aq:
break;
default:
printf("?? getopt returned character code 0%o ??\en", c);
}
}
if (optind < argc) {
printf("non\-option ARGV\-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\en");
}
exit(EXIT_SUCCESS);
}
评论区