1

optargでatoiを使用しようとしていますが、何でもかまいません。getopt_longが機能しない理由を理解しようとしています。switchステートメントを入力すると、optargはnullに設定され、そのままになります。コロンを確認しましたが、正しいです。これは私のコードです。

static struct option long_options[] = 
    {
        {"algorithm", required_argument, 0, 'a'},
        {"reverse", no_argument, 0, 'r'},
        {"key", required_argument, 0, 'k'},
        {"output", required_argument, 0, 'o'},
        {"help", no_argument, 0, 'h'},
        {"version", no_argument, 0, 'V'},
        {0, 0, 0, 0}
    };

int option_index = 0;
int c;
//Getopt to get the correct options from the command line.
while ((c = getopt_long(argc, argv, "a:rk:o:hV", long_options, 
        &option_index)) != -1)
{
    bool endOption = false;

    if (endOption) break;

    switch (c) 
    {
        case 0:
        {
            endOption = true;
            break;
        }
        case 'a':
        {
            if (optarg == "insertion") algorithm = 0;
            break;
        }

        case 'r':
        {
            reverseFlag = true;
            break;
        }
        case 'k':
        {
            while (optarg != " ")
            {
                if (optarg == ",")
                {
                    optarg++;
                }
                else 
                {
                    sortOrder.push_back(atoi(optarg)); //error here
                    optarg++;
                }
            }
        }
        case 'o':
        {
            fileFlag = true;
            break;
        }
        case 'h':
        case 'V':
        default:
        {
            cerr<<"You have entered an incorrect flag, do it better"<<endl;
            break;
        }
    }
}

//その他//

私はダブルコロンと他のほとんどすべてを使用してみました。

4

1 に答える 1

2

次のような文字列を比較することはできません。

 if (optarg == "insertion") algorithm = 0;

strcmp()次のように、または同等のものを使用する必要があります。

if (strcmp(optarg, "insertion") == 0) algorithm = 0;

他にも問題があるかもしれませんが、すぐに思い浮かびます。


optargやることをいじくり回すoptarg++のは、おそらく良い考えではありません。それは機能からあなたへの情報です。それを変更するのは危険です。ポインターのコピーを取得し、それをインクリメントして、ポインターが指す文字列をステップ実行できます。の引数にスペースが含まれるという保証は確かにありません。これが-k問題の原因である可能性がありますstrcmp()

breakafterが欠けているようですcase 'k':

ループの本体のbool endOption内側は奇妙falseです。反復ごとに設定されます。静止している間にテストされるfalseため、break実行されません。戻るtrueときに設定されます。ただし、値は次の反復の前にリセットされます。おそらく、この変数はメインループの外で宣言する必要があります。その後、賢明に動作します(ただし、ループが設定されている場合は、再度呼び出す前にループを終了する必要があります。そのため、ループの条件はメインループの最後にあるはずです。getopt_long()0while ((c = getopt_long(...)) != -1)getopt_long()while


-k処理中のループ テストをwhile (strcmp(optarg, "") != 0)(主な違いは 2 つの二重引用符の間にスペースがないことです) に変更すると、正常な動作が得られます。何が実行されているかを確認できるように、オプションをどのように装備したかに注目してください。スペースを含む文字列との比較を実行すると、ループが終了する前に環境の派手なダンプが得られました。それがコアダンプにつながるようなものです。

#include <getopt.h>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;

static struct option long_options[] = 
{
    {"algorithm", required_argument, 0, 'a'},
    {"reverse", no_argument, 0, 'r'},
    {"key", required_argument, 0, 'k'},
    {"output", required_argument, 0, 'o'},
    {"help", no_argument, 0, 'h'},
    {"version", no_argument, 0, 'V'},
    {0, 0, 0, 0}
};

int main(int argc, char **argv)
{
    vector<int> sortOrder;
    int option_index = 0;
    int c;
    bool reverseFlag = false;
    int algorithm = 1;
    bool fileFlag = false;

    //Getopt to get the correct options from the command line.
    while ((c = getopt_long(argc, argv, "a:rk:o:hV", long_options, &option_index)) != -1)
    {
        bool endOption = false;

        if (endOption) break;

        switch (c) 
        {
            case 0:
                    cerr << "Found 0 value\n";
                    endOption = true;
                    break;
            case 'a':
                    cerr << "Found -a option: " << optarg << endl;
                    if (strcmp(optarg, "insertion") == 0)
                        algorithm = 0;
                    break;
            case 'r':
                    cerr << "Found -r option\n";
                    reverseFlag = true;
                    break;
            case 'k':
                    cerr << "Found -k option: " << optarg << endl;
                    while (strcmp(optarg, "") != 0)
                    {
                        if (strcmp(optarg, ",") == 0)
                            optarg++;
                        else 
                        {
                            cerr << "pushback <<" << optarg << ">>\n";
                            sortOrder.push_back(atoi(optarg)); //error here
                            optarg++;
                        }
                    }
                    break;
            case 'o':
                    cerr << "Found -o option: " << optarg << endl;
                    fileFlag = true;
                    break;
            case 'h':
            case 'V':
            default:
                    cerr << "You have entered an incorrect flag, do it better" << endl;
                    break;
        }
    }
}

それが次のように実行される場合:

./getopt -k 2,1

私は出力を得ました:

Found -k option: 2,1
pushback <<2,1>>
pushback <<,1>>
pushback <<1>>

比較を次のように変更したい場合があります。

if (strcmp(optarg, ",") == 0)

に:

if (*optarg == ',')

ループ条件を次のように合理的に変更することもできます。

while (*optarg != '\0')

strcmp()したがって、完全に避けてください。ちなみに、どのヘッダーが を引っ張ったかはわかりませんが<cstring>、そのうちの 1 つが引っ込みました。


記録のために、MacOS X 10.7.2 (Lion) を実行し、提供されている G++ コンパイラを使用して Mac Mini でテストしていますi686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)

于 2012-02-13T05:51:28.023 に答える