2012-01-11 8 views

答えて

1

私はBoost.Program_optionsのドキュメントを読み飛ばしましたが、それができるかどうかはわかりません。ライブラリが主にの構文解析を検証していないという印象を受けます。あなたはcustom validatorで何かをすることができるかもしれませんが、悪い入力があったときに例外がスローされます(これはあなたが望むより重大なエラーかもしれません)。私はその機能が、あなたが実際に文字列を持っているかどうかを確かめるために、それが "猫"か "犬"ではないと考えています。

私は考えることができる最も簡単な解決策は、--argcatまたはdogに設定したことを確認するために、後で独自のコードを追加し、ライブラリは通常通り、コマンドラインを解析できるようにすることです。その後、エラーを出力して終了するか、適切なデフォルトに戻すか、好きなものに戻すことができます。

17

custom validator機能を使用できます。オプションに固有の型を定義し、その型の関数validateをオーバーロードします。

struct catdog { 
    catdog(std::string const& val): 
    value(val) 
    { } 
    std::string value; 
}; 

void validate(boost::any& v, 
       std::vector<std::string> const& values, 
       catdog* /* target_type */, 
       int) 
{ 
    using namespace boost::program_options; 

    // Make sure no previous assignment to 'v' was made. 
    validators::check_first_occurrence(v); 

    // Extract the first string from 'values'. If there is more than 
    // one string, it's an error, and exception will be thrown. 
    std::string const& s = validators::get_single_string(values); 

    if (s == "cat" || s == "dog") { 
    v = boost::any(catdog(s)); 
    } else { 
    throw validation_error(validation_error::invalid_option_value); 
    } 
} 

そのコードからスローされた例外は、他の無効なオプション値のためにスローされた例外と違いはありませんので、あなたはすでにそれらを処理するために準備しなければなりません。

使用代わりに、あなたのオプションを定義するときだけstringの特別なオプションの種類は:

desc.add_options() 
    ("help", "produce help message") 
    ("arg", po::value<catdog>(), "set animal type") 
; 

私はlive example demonstrating use of this codeを作曲しました。

+0

この例では、[公式ドキュメント](http://www.boost.org/doc/libs/1_55_0/doc/html/program_options/howto.html#idp163429032)で提供1と非常によく似ています。しかし、抽出演算子関数を実装する必要があります 'std :: istream&operator >>(std :: istream&in、catdog&cd)' '{' 'return in.value;' '} ' ' – russoue

+1

はい、@ Russoue、私のコードは私が以前にリンクしたドキュメントから直接適合しています。私はなぜコードがストリーム抽出を必要としていると思うのか分かりません。私は、あなたの主張を偽っている実用的な例を含めました。ドキュメントは 'lexical_cast'を使用して入力文字列を目的のデータ型に変換します。同じテクニックを使用する場合は、実際には' operator >> 'を実装する必要があります。私の例では、直接構築を使用しています。 *文字列からカスタムタイプを作成する方法は、この質問の対象外です。 –

5

非常に簡単なアプローチは、通常の文字列として「動物」を使用し、必要に応じてテストしてスローすることを通知した後です。

if (vm.count("animal") && (!(animal == "cat" || animal == "dog"))) 
     throw po::validation_error(po::validation_error::invalid_option_value, "animal"); 
+0

これはMichaelが示唆したものではありませんか? –

+0

@RobKennedy「マイケルはあなたができることがあります」と言ったのに対し、ジョルゲンは「ここでできることは何ですか? –

関連する問題