2012-02-13 5 views
1

状態(例:合格/不合格)が変更されるたびにメッセージを一度ログに記録する必要があるdo-whileループがあるため(ログが乱雑にならない)それがループを通過するたびに他のことをする。単純なブール変数を使用すると、基本的にはあなたがすでに既知の状態になっている、そのメッセージをすでに記録しているかどうかを知ることができます。ただし、どちらの場合でもメッセージが最初に印刷されるようにするには(合格/不合格)、そのことを考慮する必要があります。たとえば、条件をtrueにデフォルト設定し、実際には初めての場合、True(真)のメッセージはログに記録されず、それはすでに真であると考えられます(逆も同様です) )。do-whileの最初のパスを検出する

これは、nullableブール値のi.c. = Nullの場合に適しているようですが、それらが存在しない言語では、何をするべきですか?

私が考えることができる最も簡単な解決策は、 'firstTime = True'のような余分なブール変数を使用することですが、それを使用すると、それを扱うより繊細な方法。もう1つのオプションは、do-whileのブレークアウト条件を、条件として使用している変数の初期条件として使用することですが、誰かがint status = STATUS_QUITを読み込んだときに混乱する可能性があり、確かにbool firstTime = trueより多くの説明コメントが必要です。 3番目のオプションは、boolの代わりにenumを使用し、{firstTime、true、false}か何かを持つことです。

もう1つを使用する別の理由がありますか、これを行うには良い方法がありますか?

二つのオプションを持つコード例私が思い付いた:bool firsttimeを使用して

bool firstTime = true, infoFound = false; 
do 
{ 
    if (getInfo()) 
    { 
     if (!infoFound) 
     { 
      // log it (ONCE)(important) 
      infoFound = true; 
     } 
     // use info (every time) 
    } 
    else if (infoFound || firstTime) 
    { 
     // log it (ONCE)(important) 
     infoFound = false; 
     firstTime = false; 
    } 
// FYI, WaitForStatusUpdate is a blocking call... 
} while (STATUS_QUIT != WaitForStatusUpdate()); 

チェック変数の初期条件としてwhileループ「ブレイクアウト状態」を使用します。
statusはdo-whileの最後に更新されるため、doセクションは再び実行されません。status == breakOutCondition;我々はここに私達の利点にこれを使用すると、最初はstatus = breakOutContitionを設定することができます - それはハックのようなものだとして、それを通じて初めてbreakOutConditionになりますが、それ以降のループが他の何か...となりますそれでも確か私はこれが好きではありません.. 。

bool infoFound = false; 
int status = STATUS_QUIT; 
do 
{ 
    if (getInfo()) 
    { 
     if (!infoFound) 
     { 
      // log it (ONCE)(important) 
      infoFound = true; 
     } 
     // use info (every time) 
    } 
    else if (infoFound || firstTime) 
    { 
     // log it (ONCE)(important) 
     infoFound = false; 
    } 
    status = WaitForStatusUpdate(); 
} while (STATUS_QUIT != status); 

(それは私が使用しているものだが、これは本当に似た構造を持つ任意の言語に適用する可能性があるので、私はC++としてこれをタグ付けしています)

+1

C++を使用している場合は、 'BOOL'と' TRUE/FALSE'ではなく 'bool'と' true/false'を使用してください。 –

+0

@DavidRodríguez-dribeas:ええ、私たちはwindefを使用しています。hは '#define FALSE 0'を持っていますが、ここでは' false'に変更して、他の人がコンパイルするなどしてコンパイルすることはできません...良いキャッチ:) – johnny

+0

不思議なことに(あるいは多分? 'BOOL'を' int'と定義していますので、整数(または列挙型)を使用して同等の結果を得ることができました...しかし、もう一度、Windows固有の質問 – johnny

答えて

2

列挙型は明確になりませんか?

enum State { Unknown, Pass, Fail }; 
State state = Unknown; 
... 
State newState = getInfo() ? Pass : Fail; 
if (newState != state) { log(); state = newState; } 
+1

これは私の元々の思想(OPで参照されている「第3のオプション」)の1つでした。おそらくそれはすべての後で最もきれいですが、私はそれが過度の可能性を考えたと思いますか?いずれにしても、私は他の人が何を考えているのか興味を持っていました... – johnny

+0

enumを使用することに私がひどく部分的ではない理由の1つは、次のような条件を使わずに状態をチェックする良い方法を考えることができないということです単純に 'if(infoFound)'( 'bool state')とは対照的に' if((infoFound == state)||(newState == state)) '('状態ステート 'しかし、これは好みの問題にとどまるかもしれません... – johnny

+0

これはアルゴリズムの明確な表現です。私はあなたの2つの旗で混乱します。しかし、それはまさに味の問題かもしれません。 –

1

C++ほとんどNULL可能ブール値を持っている、boost::optional<bool>を行うだろうトリック私は信じています。

C++でこれを行う一般的な方法の1つは、適切なコンテキストで作成するストリームラッパーで、フラッシュされた回数などを記憶しています。ロギングを通常どおりに行い、ラップされたストリームにストリームを送信するかどうかをストリームに決定させます。

+0

ストリームラッパーのアイデアをありがとう - 私はそれを調べなければなりません - それは確かにそれ以上の仕事かもしれませんこのアプリケーションの価値はありますが、一般的には良い実装になるかもしれません... – johnny

+0

ブーストを使用している場合、['boost :: logic :: tribool'](http://www.boost.org/doc/libs/release/doc /html/boost/logic/tribool.html)が便利かもしれません。 –

関連する問題