c - getopt() 解析模式不起作用
问题描述
根据手册页, getopt() 具有三种不同的解析模式
默认情况下,getopt() 会在扫描时置换 argv 的内容,以便最终所有非选项都位于末尾。还实现了另外两种模式。如果 optstring 的第一个字符是 '+' 或设置了环境变量 POSIXLY_CORRECT,则一旦遇到非选项参数,选项处理就会停止。如果 optstring 的第一个字符是 '-',则每个非选项 argv- 元素都被处理为就好像它是具有字符代码 1 的选项的参数一样。(这被编写为期望选项和其他 argv 元素的程序使用以任何顺序,并且关心两者的顺序。)特殊参数“--”强制结束选项扫描,而不管扫描模式如何。
在我的 Centos 7 上,似乎 '+'/'-' 符号无法切换解析模式,它们都给出相同的结果,这是我的测试代码:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void parse(int argc, char * const argv[], const char *optstr)
{
printf("opterr: %d optstr: %s optargs: ", opterr, optstr);
for (int i = 0; i < argc; ++i) {
printf("%s ", argv[i]);
}
printf("\n");
int opt = -1;
optind = 1;
while ((opt = getopt(argc, argv, optstr)) != -1) {
printf("optind: %d optopt: %d "
"optarg: %s opt: %c\n",
optind, optopt, optarg, (char)opt);
}
printf("unparsed: ");
for (int i = optind; i < argc; ++i) {
printf("%s ", argv[i]);
}
printf("\n");
}
void nonoption()
{
const char *optstr = "ab";
char *argv[] = {"", "-a", "hello", "-b", "world"};
parse(5, argv, optstr);
}
void posix_nonoption()
{
const char *optstr = "+ab";
char *argv[] = {"", "-a", "hello", "-b", "world"};
parse(5, argv, optstr);
}
void nonoption1()
{
const char *optstr = "-ab";
char *argv[] = {"", "-a", "hello", "-b", "world"};
parse(5, argv, optstr);
}
int main(int argc, char *argv[])
{
nonoption();
posix_nonoption();
nonoption1();
return 0;
}
这是输出:
opterr: 1 optstr: ab optargs: -a hello -b world
optind: 2 optopt: 0 optarg: (null) opt: a
optind: 4 optopt: 0 optarg: (null) opt: b
unparsed: hello world
opterr: 1 optstr: +ab optargs: -a hello -b world
optind: 2 optopt: 0 optarg: (null) opt: a
optind: 4 optopt: 0 optarg: (null) opt: b
unparsed: hello world
opterr: 1 optstr: -ab optargs: -a hello -b world
optind: 2 optopt: 0 optarg: (null) opt: a
optind: 4 optopt: 0 optarg: (null) opt: b
unparsed: hello world
解决方案
如果你看一下getopt
手册,你会发现这一段:
扫描多个参数向量,或多次重新扫描同一个向量,并希望在 optstring 的开头使用 GNU 扩展,例如 '+' 和 '-',或在扫描之间更改 POSIXLY_CORRECT 的值的程序,必须通过将 optind 重置为 0 而不是传统值 1 来重新初始化 getopt()。(重置为 0 会强制调用内部初始化例程,该例程重新检查 POSIXLY_CORRECT 并检查 optstring 中的 GNU 扩展。)
您必须设置optind
为0
in function parse
,然后它将起作用。
推荐阅读
- momentjs - 当我格式化时,时刻 js 显示错误的时间
- formula - 如何根据经纬度计算偏移量
- python - 父类 self.__class__.__name__ 打印子类的名称
- javascript - 同一页面上的两个 Off Canvas 侧边栏
- javascript - 使用 laravel 和 vue.js 提交数据后显示消息
- c# - C# 从没有结束字符的网络流中读取
- sql - 左连接计数来自第二个表的三个属性
- r - 使用do.call将数据帧列表转换为具有多列的单个数据帧在R中的循环中不起作用
- javascript - 使javascript ip地址正则表达式拒绝数字0
- hardware - Epyc 2 是否具有与 DDIO 等效的功能?