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

問題は、引数が解析される方法ではありません。問題は、コードが引数を表示する方法です。具体的には、オプションと引数の間にスペースがある場合、 はoptind2 つ進みます。 配列内の次のインデックスを追跡するために使用optindする外部変数です。getoptargv

したがって、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初めて呼び出すと、 が読み取られ、指定したオプションの 1 つとしてargv[1]認識さ-aれるため、文字列を 2 つの部分に分割し、 を に設定しながら を返し'a'ます。optarg"1"

2 回目に呼び出すと、オプションgetoptが読み込まargv[2]れ、認識され-bます。-b引数を取るが、引数をargv[2]含まないことを指定したので、引数としてgetopt取りargv[3]ます。したがって、'b'を に設定しながら をoptarg返します"2"

getopt肝心なのは、オプションとその引数の間の空白を無視するように設計されていることです。argvユーザーがオプションとその引数の間に空白を入れると、2 つの文字列が処理されます。

于 2014-03-30T06:43:40.760 に答える