0

ファイルからの入力を解析して、標準的なカードのデッキを表現しようとしています (つまり、2C は 2 つのクラブを表します)。ただし、私のソリューションは期待どおりに機能しておらず、すべての入力が無効であると宣言しています。コードに論理エラーが見当たらないので、セカンドオピニオンを得たいと思いました。コードは以下のとおりです。

/*
 * Determines if the input string is valid.
 * 
 * A string is considered valid if it begins with either a number (2-10) 
 * or a letter (J/j, Q/q, K/k) to deetermine rank, followed by a letter to
 * determine suit (C/c, D/d, H/h, S/s).
 */
bool inputValidator(string cardData)
{
    if (cardData.length() == 2) //Input string is two characters long
    {
        if (cardData[0] < '2' || cardData[0] > '9'
            || cardData[0] != 'J' || cardData[0] != 'j'
            || cardData[0] != 'Q' || cardData[0] != 'q'
            || cardData[0] != 'K' || cardData[0] != 'k'
            || cardData[0] != 'A' || cardData[0] != 'a')
        {
            cout << "Card with data " << cardData << " has an invalid rank." << endl;
            return false;
        }
        if (cardData[1] != 'C' || cardData[1] != 'c' //Parse suit
            || cardData[1] != 'D' || cardData[1] != 'd'
            || cardData[1] != 'H' || cardData[1] != 'h'
            || cardData[1] != 'S' || cardData[1] != 's')
        {
            cout << "Card with data " << cardData << " has an invalid suit." << endl;
            return false;
        }
        return true;
    }
    else if (cardData.length() == 3) //Input string is three characters long
        //This occurs only if the number is 10.
    {
        if (cardData[0] != '1' || cardData[1] != '0') //Parse rank
        {
            cout << "Card with data " << cardData << " has an invalid rank." << endl;
            return false;
        }
        if (cardData[2] != 'C' || cardData[2] != 'c' //Parse suit
            || cardData[2] != 'D' || cardData[2] != 'd'
            || cardData[2] != 'H' || cardData[2] != 'h'
            || cardData[2] != 'S' || cardData[2] != 's')
        {
            cout << "Card with data " << cardData << " has an invalid suit." << endl;
            return false;
        }
        return true;
    }
    return false;
}

論理的な欠陥 (またはこれを行うための本質的により良い方法) がある場合は、教えていただければ幸いです。ありがとう。

4

4 に答える 4

4

次のような句を書いています。

cardData[2] != 'D' || cardData[2] != 'd'

テストされる変数が同時に両方の値になることはできないため、これは常に真です。おそらく、&&ではなくを使用するつもり||でした。

たとえば、入力を比較する前に小文字または大文字に変換するなど、ロジックを単純化できます。

于 2013-02-01T22:28:43.527 に答える
2

問題は、条件を組み合わせる方法にあるようです。あなたの期待を正しく理解していれば、最初の条件に必要なものは次のとおりです。

    if (!(cardData[0] > '2' && cardData[0] < '9')
        && cardData[0] != 'J' && cardData[0] != 'j'
        && cardData[0] != 'Q' && cardData[0] != 'q'
        && cardData[0] != 'K' && cardData[0] != 'k'
        && cardData[0] != 'A' && cardData[0] != 'a')

そして、2番目の条件に必要なものは次のとおりです。

    if (cardData[1] != 'C' && cardData[1] != 'c' //Parse suit
        && cardData[1] != 'D' && cardData[1] != 'd'
        && cardData[1] != 'H' && cardData[1] != 'h'
        && cardData[1] != 'S' && cardData[1] != 's')
于 2013-02-01T22:33:16.543 に答える
1

条件を少し単純化することができます。そして、条件を変更して、やりたいことを実行する必要があります。

bool inputValidator(string cardData)
{
    if (cardData.length() == 2) //Input string is two characters long

   {
        if (!((cardData[0] >= '2' && cardData[0] <= '9')
            || (cardData[0]|32) == 'j'
            || (cardData[0]|32) == 'q'
            || (cardData[0]|32) == 'k'
            || (cardData[0]|32) == 'a'))
        {
           cout << "Card with data " << cardData << " has an invalid rank." << endl;
           return false;
         }

        if (!((cardData[1]|32) == 'c' //Parse suit
            || (cardData[1]|32) == 'd'
            || (cardData[1]|32) == 'h'
            || (cardData[1]|32) == 's'))
        {
            cout << "Card with data " << cardData << " has an invalid suit." << endl;
            return false;
        }
        return true;
    }
    else if (cardData.length() == 3) //Input string is three characters long
        //This occurs only if the number is 10.
    {
        if (!(cardData[0] == '1' || cardData[1] == '0')) //Parse rank
        {
            cout << "Card with data " << cardData << " has an invalid rank." << endl;
            return false;
        }
        if (!((cardData[2]|32) == 'C' //Parse suit
            || (cardData[2]|32)  == 'd'
            || (cardData[2]|32)  == 'h'
            || (cardData[2]|32)  == 's'))
        {
            cout << "Card with data " << cardData << " has an invalid suit." << endl;
            return false;
        }
        return true;
    }
    return false;
}

2 番目と 3 番目の文字のコードの重複もリファクタリングする必要があります。

于 2013-02-01T22:33:30.757 に答える
1

あなたの論理式は正しくありません。また、コードを複製しています。それらを単純に関数にしようとしています。

bool inputValidator(string cardData)
{
    if (cardData.length() == 2 && IsValidCard(cardData[0])) //Input string is two characters long
    {
        return IsValidSuite(cardData[1]);
    }
    else if(cardData.length() == 3) 
    {
        if (isValidRank(cardData[0]))
        {
            return IsValidSuite(cardData[2]);
        }
    }
    return false;
}

bool isValidRank(char c)
{
    if (c =='0' || c=='1')[
    {
        return true;
    }
    return false;
}

bool IsValidCard(char c)
{
  if (c > '2' && c < '9')
  {
    return true;
  }

  switch(c)
  {
    case 'J':
    case 'j':
    case 'Q':
    case 'q':
    case 'K':
    case 'k':
    case 'A':
    case 'a':
      return true;
  }

  return false;
}    

bool IsValidSuite(char c)
{
  switch(c)
  {
    case 'C':
    case 'c':
    case 'D':
    case 'd':
    case 'H':
    case 'h':
    case 'S':
    case 's':
      return true;
  }
  return false;
}
于 2013-02-01T22:38:47.720 に答える