1

I am creating a program for an online coding course which takes a poker hand and calculates the odds of the hand winning. I am currently in the early stages, writing the functions necessary to advance to the next part of the assignment. I have isolated my issues to one function, card_from_letters.

I created my-test-main.c to test card_from_letters. It creates two chars, representing the suit and value of a poker card. It then creates the struct testCard2.

A card_t struct has two components: an unsigned int for value, and an enumerated type for suit between SPADES and CLUBS. I cannot change the struct card_t.

int main(void) {
    char sui = 'c';
    char val = 'Q';
    card_t testCard2 = card_from_letters(val, sui);
    printf("last test! My card %c%c is value %d, and suit %d!\n", val, sui, testCard2.value, testCard2.suit);
}

This is my function card_from_letters:

card_t card_from_letters(char value_let, char suit_let) {
    card_t temp;
    assert(suit_let == 'd' ||'h' || 'c' || 's');
    assert((value_let >= '2' && value_let <= '9') || (value_let = '0' || 'K' || 'Q' || 'J' || 'A'));

    switch (value_let) {
        case '2': temp.value = 2; break;
        case '3': temp.value = 3; break;
        case '4': temp.value = 4; break;
        case '5': temp.value = 5; break;
        case '6': temp.value = 6; break;
        case '7': temp.value = 7; break;
        case '8': temp.value = 8; break;
        case '9': temp.value = 9; break;
        case '0': temp.value = 10; break;
        case 'K': temp.value = 13; break;
        case 'Q': temp.value = 12; break;
        case 'J': temp.value = 11; break;
        case 'A': temp.value = 14; break;
    }
    switch (suit_let) {
        case 's': temp.suit = SPADES; break;
        case 'h': temp.suit = HEARTS; break;
        case 'd': temp.suit = DIAMONDS; break;
        case 'c': temp.suit = CLUBS; break;
    }
    return temp;
}

When val is set between '2' and '9', I am able to run card_from_letters with no problem. When I run my-test-main.c as it is here through gdb, the execution arrow makes it to switch (value_let), but then skips all cases and enters switch (suit_let), where it returns the correct suit. What am I missing here? How come card_from_letters works for chars 2 to 9, but not 0 to A?

GSerg
  • 76,472
  • 17
  • 159
  • 346
Quinn
  • 33
  • 3
  • 4
    `suit_let == 'd' ||'h' || 'c' || 's'` and `value_let = '0' || 'K' || 'Q' || 'J' || 'A'` do not do what you think they do. The latter even for more than one reason. – GSerg Jul 04 '21 at 15:30
  • 1
    Does this answer your question? [Why are my or operators not working as intended? (C++)](https://stackoverflow.com/questions/61716473/why-are-my-or-operators-not-working-as-intended-c) – GSerg Jul 04 '21 at 15:40
  • 1
    At least one bug here: `value_let = '0'`. You should have `value_let == '0'`. – anatolyg Jul 04 '21 at 15:44
  • Does this answer your question? [error in if condition even i enter code correctly in c programming](https://stackoverflow.com/q/15093004/11683) – GSerg Jul 04 '21 at 15:44
  • Thank you for your insight, @GSerg. I see that 'value_let = '0'' is not written as a conditional statement. Would you happen to know why assert accepts value_let in its current form despite it not being a conditional statement? – Quinn Jul 04 '21 at 15:51
  • Why wouldn't it? An [assignment is a valid expression](https://stackoverflow.com/a/35066685/11683) the result of which is the value assigned. – GSerg Jul 04 '21 at 15:53
  • 1
    _Side note:_ You can eliminate the `assert` by just having in your `switch` a (e.g.) `default: abort(); break;` – Craig Estey Jul 04 '21 at 16:05
  • I would add to @CraigEstey 's comment that the assertions only hold for DEBUG code, you must always cover the boundary conditions by other means anyway. – jwdonahue Jul 04 '21 at 20:49

0 Answers0