2012-05-11 8 views
4

私は(それが起こるように、テキストゲーム、)いくつかの古いコードと協力し、よりよい何かをパターン可変個引数の文字列の比較

strcasecmp(variable, "something") == 0 || strcasecmp(variable, "something else") == 0 

を交換したかった、

in_list(variable, "something", "something else") 

ように私は思いました。可変的な機能が適切であろう。しかし、私がマンページを見ると、引数が足りなくなったときを知らせる方法がないことがわかりました(定義されていない動作の結果があるときはva_argと呼んでいます)。だから私はこれをどう扱うことができますか?

多分、この制限を回避する方法があります。たぶん私は#defineリストの最後にいくつかの種類のセンチネルがありますので、私はそれをチェックすることができますが、それは控えめなようです。私はちょうどそれがハックのように感じるが、私はちょうど1つ、2、...引数をいくつかの合理的な制限まで、マクロの家族とそれを置き換えることができると思います。

これは正しい方法はありますか? stringタイプを使用するようにプログラムを書き直すつもりはなく、私はchar*で止まっているとします。

in_list(variable, {"something", "something else", "yet a third thing"}); 

編集:あなたがC++ 11個の機能を使用することができますのようなものを使用することができますので、私は、関数が初期化子リストをサポートコレクション型(例えば、std::set)を取る必要があるだろうと仮定し

+0

'char *'で「固まっている」場合は、明らかにセンチネル値 - NULLです。 ( 'std :: set'ソリューションははるかにクリーンで簡単ですが) –

答えて

6

ここでは簡単デモだ:

#include <string> 
#include <set> 
#include <iostream> 

bool in_list(std::string const &value, std::set<std::string> const &list) { 
    return list.find(value) != list.end(); 
} 

int main(){ 
    std::cout << std::boolalpha << in_list("true", {"this", "is", "a", "true", "statement"}) << "\n"; 

    std::cout << in_list("false", {"this", "is", "a", "true", "statement"}); 
    return 0; 
} 

これは、G ++ 4.7.0できれいにコンパイルし、期待される出力を生成します

true 
false 

そうでなければ理由がなければ、std::setは手元にある仕事の合理的な選択肢になります。 char *と比べてstd::stringの場合、std::stringは暗黙の変換をchar *からサポートしているので、関数にはchar *を渡すことができます(上記のとおり)。これは自動的にstd::stringに変換されます。言い換えれば、(ほとんどの)他のコードは、char *を渡すことができ、このコードではstd::stringと表示されるマイナーな詳細について心配する必要はありません。

+0

私はC++ 0x機能、または少なくともgccでサポートされているサブセットを使用できます。しかし、私はこれを実際に動作させるのに少し問題があります。 'std :: set'は実際にジョブの正しいツールですか?私はそれをテストする3つの機能を書いたが、意図したとおりに動作させることができなかった。 – Charles

+0

@Charles:答えに短いデモコードを追加しました。 –

+0

うわー、そのコードは、私がコーディングしたどのバージョンよりもはるかにクリーンで優れています。小道具! – Charles