0

我输入以下命令行:

./file -a 1 -b2 -a5 -b 55 -b4

我得到的输出是:

a: 1
argv[1]: -a
b: 2
argv[2]: 1
a: 5
argv[3]: -b2
b: 55
argv[4]: -a5
b: 4
argv[5]: -b
Counter: 5

我希望得到的输出应该是:

a: 1
argv[1]: -a 1
b: 2
argv[2]: -b2
a: 5
argv[3]: -a5
b: 55
argv[4]: -b 55
b: 4
argv[5]: -b4
Counter: 5

带有空格的参数当前被计为 2 个参数。我希望我的程序仅将其视为 1 个参数(我希望它看到“-a 1”。而不是分别看到“-a”和“1”)。

这是我使用的源代码,我得到了输出:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>

int main(int argc, char *argv[]) 
{
    int opt = 0;
    int quantum1 = 0, quantum2 = 0;
    int counter = 0;

    while ((opt = getopt(argc, argv,"a:b:")) != -1) 
    {
        switch (opt) 
        {                           
             case 'a' : 
                quantum1 = atoi(optarg); 
                printf("a: %d\n", quantum1);
                break;

             case 'b' : 
                quantum2 = atoi(optarg);
                printf("b: %d\n", quantum2);
                break;

             default: 
                printf("Error\n");
                return 1;
                break;
        }
        counter++;
        printf("argv[%d]: %s\n", counter, argv[counter]);
    }

    printf("Counter: %d\n", counter);

    return 0;
}

注意:引号建议工作,但我不允许使用引号或任何其他符号。

4

2 回答 2

2

利用

./file "-a 1" -b2 -a5 "-b 55" -b4

将“-a 1”作为第一个参数,将“-b 55”作为第四个参数。

如果现在允许使用引号,则可以使用以下命令转义 linux 中的空格:

./文件 -a\ 1 -b2 -a5 -b\ 55 -b4
于 2014-03-30T06:22:20.887 回答
2

问题不在于解析参数的方式。问题在于代码显示参数的方式。Specifically, when a space exists between the option and the argument, the optindwill advance by two. optind是一个外部变量,getopt用于跟踪argv数组的下一个索引。

因此,如果您简单地消除counter下面显示的 和 行,您会发现您的代码已经正常工作。

    counter++;
    printf("argv[%d]: %s\n", counter, argv[counter]);

printf("Counter: %d\n", counter);

如果您绝对必须计算找到的参数数量,则只需更新counter每个case语句中的

        case 'a' :
            counter++;
            ...

        case 'b' :
            counter++;
            ...

然后在最后打印计数器。这printf("argv[%d]: %s\n", counter, argv[counter]);条线让你感到困惑。该行没有任何用处,应删除。


对于 的命令行./test -a1 -b 2, argv 中的字符串将是

argv[0]: "./test"
argv[1]: "-a1"
argv[2]: "-b"
argv[3]: "2"

当您第一次调用getopt时,它将读取argv[1]并将 识别-a为您指定的选项之一,因此它将字符串分成两部分并返回'a'while 设置optargto "1"

当您getopt第二次调用时,它将读取argv[2]并识别该-b选项。由于您已指定-b接受参数但argv[2]不包含参数,getopt因此将argv[3]作为参数。因此它返回'b'while 设置optargto "2"

底线getopt是旨在忽略选项及其参数之间的空白。argv如果用户在选项和它的参数之间放置空格,它会通过处理两个字符串来做到这一点。

于 2014-03-30T06:43:40.760 回答