我的论点是这样的
./a.out -i file1 file2 file3
如何利用getopt()
获取3个(或更多)输入文件?我正在这样做:
while ((opt = getopt(argc, argv, "i:xyz.."))!= -1){
case 'i':
input = optarg;
break;
...
}
我只获取了file1
,如何获取file2
和file3
?
我知道这已经很老了,但我在寻找解决方案时遇到了它。
while((command = getopt(argc, argv, "a:")) != -1){
switch(command){
case 'a':
(...)
optind--;
for( ;optind < argc && *argv[optind] != '-'; optind++){
DoSomething( argv[optind] );
}
break;
}
我发现getopt()使用的extern参数int optind指向'当前argv'选定后的下一个位置;这就是为什么我在开头将其减少的原因。
首先,for循环检查当前参数值是否在argv的边界内(argc是数组的长度,所以数组argv中的最后一个位置是argc-1)。 第二部分的&&比较下一个参数的第一个字符是否为'- '。如果第一个字符是'-',则我们已经没有当前参数的下一个值,否则argv[optind]就是我们的下一个值。依此类推,直到argv结束或参数用尽。
最后递增optind以检查下一个argv。
请注意,因为我们首先检查'optind < argc',所以除非第一部分为真,否则不会执行条件的第二部分,因此不必担心超出数组边界问题。
PS 我是个相当新的C程序员,如果有人有改进或批评,请分享一下。
strlen(argv[optind])
等于 2。这将确保它能正确处理以破折号开头的参数。不过,这段代码对我很有帮助!+1 - TheBat-whatever
这样的参数对吧,@TheBat?我有点困惑,因为你所说的对 getopt_long
是行不通的。 - user129393192-whatever
这样的参数对吧,@TheBat?我有点困惑,因为你所说的对 getopt_long
是行不通的。 - undefinedargv[optind]
开始并自己增加optind
。但是,我建议不要这样做,因为我认为这种语法形式很差。(你怎么知道何时到达列表末尾?如果有人的文件以-
作为第一个字符命名呢?)/a.out -i file1 -i file2 -i file3
或者将文件列表视为位置参数:
/a.out file1 file2 file3
我查看并尝试了上面的代码,但我发现我的解决方案更简单,而且对我来说效果更好:
我需要的处理方式是:
-m mux_i2c_group mux_i2c_out
需要2个参数。
以下是我的实际应用示例:
case 'm':
mux_i2c_group = strtol(optarg, &ch_p, 0);
if (optind < argc && *argv[optind] != '-'){
mux_i2c_out = strtol(argv[optind], NULL, 0);
optind++;
} else {
fprintf(stderr, "\n-m option require TWO arguments <mux_group> "
"<mux_out>\n\n");
usage();
}
use_mux_flag = 1;
break;
这个程序首先像平常一样获取了第一个值,然后寻找第二个必需的值。
GoTTimw的解决方案对我非常有用。但是,我想提出另一个想法,这里还没有提出。
以这种方式将参数作为一个字符串传递。
./a.out -i "file1 file2 file3"
然后您会得到一个字符串作为单个参数,您只需要按空格拆分它。
getopt()
为命令行选项提供两个参数的问题提供了一些在这里未提及的可能性。 - Jonathan Leffleroptind
的答案,是在冒险尝试。没有文件记录说明必须在调用代码中修改getopt()
的optind
或optarg
时应该如何运行。尽管当前和可能存在的大多数实现不会有问题,但是假设性实现可以将其内部状态记录在非全局变量中,并在返回时仅设置全局变量。这样的实现将符合getopt()
的POSIX规范,但所示的改动将无法起作用。 - Jonathan Leffler