1

I'm new in C and I couldnt find the answer to my question in the forum.

The point is, I need to get a value of deck cards from the user. So it can spread from 2 to 10 and also be 'J', 'Q', 'K' or 'A'. That means it can be a integer or a character.

I'm trying to put it in an integer variable called "_val1". This work for any number from 0 to 10. I expected that if I typed a letter, _val1 would get the ASCII value of that character (wich I could use later for my pourposes). But instead _val1 geta value '0' and the letter is automatically passed to my next variable call (wich is _naipe1).

How can I solve that?

That means, how cam I use scanf to get either a integer value or the ASCII value of a character?

  short int _val1, _val2;
  char _naipe1, _naipe2;

  printf("Qual a 1ª carta?\n Valor:");
  scanf(" %hd", &_val1);
  printf("Valor 1 = %hd \n", _val1 );
  printf(" Naipe:");
  scanf(" %c", &_naipe1);
3
  • add A to the integer or did you want the other way? Commented Mar 20, 2014 at 14:33
  • 4
    you should write your code in english so everybody can understand it. Commented Mar 20, 2014 at 14:34
  • Do you also need to know suit?, i.e. heart, spade, diamond, club? Commented Mar 20, 2014 at 15:16

5 Answers 5

1

well, if I were you I'd try to simplify the problem:

  • get the ASCII value of the card representation from '2' to '9' and 'J','Q','K','A' ; there you can simply use a scanf("%c") or even better a getchar() operation.

then either you keep using the ASCII representation of your cards throughout your algorithm, or you can translate it using a mapping function such as:

int map(char card) {
    switch (card) {
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return card-'0';
        case 'A':
            return 1;
        case 'J':
            return 10;
        case 'Q':
            return 11;
        case 'K':
            return 12;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

How would you handle the 10 card?
ahah, good point, it totally breaks the algorithm I'm suggesting. There could be unelegants hacks around that to make it fit. I guess I just have to withdraw my suggestion.
1

First, there are 52 cards to a typical poker deck, These are split into 4 suits: hearts, diamonds, spades and clubs. This kind of suggests that user input will be something like: 10s, Ad, 3c, etc (meaning 10 of spades, Ace of diamonds and 3 of clubs) So, not only must you determine the value of the individual card, you also must determine the suit.

This will not solve all of those requirements, but it will at least answer your most direct question, how to read an int or a char using scanf().
This will demonstrate that:

#include <stdio.h>

int main(int argc, char** argv)
{
    int aNumber;
    char aChar;


    printf("\nEnter a number:");
    scanf("%d", &aNumber);
    printf("\nEnter a character:");
    scanf("%c", &aChar);
    printf("\nThe number entered is %d\n", aNumber);
    printf("\nThe character entered is %c\n", aChar);

    return 0;
}

You can also simply have all the values in a string such as

char cards[]={"Ad Js 10c 2c Qh"};  

Then parse it using strtok(), then test each token for its ascii content, using functions like isdigit() or isalpha()

Note: you will have to map each card to a value to keep them straight, something like this abbreviated enum may work:

enum {
   AD = 1, //start enum values at 1 for the diamonds suit
   2D,  
   3D, 
   ...//fill in rest of cards here  
   JC,  
   QC,  
   KC, // last card == 52, with the clubs suit
};  

4 Comments

I don't storing it in a string is a particularly efficient nor readable way, if you have to search through it with some obscure and slow function for each input.
@Lundin - OP is getting user input, do you really think speed or efficiency are important issues here? By the way, I find it odd that you would refer to isdigit(), strtok() and isalpha() as obscure. They are anything but for resolving user input strings in a precise way.
strtok() is quite obscure because you have to call it in two different ways. But of course C programmers are used to it, so they don't have any problems with the function. And it is certainly much slower than some manual method. But that's just nit picks. What's really important: never add extra complexity to a program unless you have to. With increased complexity comes more bugs.
@Lundin - I will agree with you on at least one point, minimizing complexity is a good way to minimize bugs. I am not sure the OP has considered all other aspects of handling user input coupled with the various ways of representing a deck of 52 cards.
0

The reason your output from _val1 is 0 when entering a letter lies in the fact that you've declared _val1 as an short int. You should be using a char. Then you can assign and compare their ascii values.

char card;
int value;
scanf("%c", card);
if(card < 58 && card > 49)
   value = card - 48;
else {
   switch(card) {
      case 'a': value = 1;
      case '0': value = 10;
      case 'j': value = 11;
      case 'q': value = 12;
      case 'k': value = 13;
      default: printf("Must enter 0-9 (0 for 10 card),  or a, j, q, k\n");
   }
}

Comments

0

To read in "A", "2", "3", ... "10", "J",... "K", use fgetc() and strchr().

#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>

short GetCardRank(void) {
  static const char rank[] = "A234567891JQK";
  short val = -1;
  int ch = fgetc(stdin);
  while (isspace(ch)) ch = fgetc(stdin); // Skip leading white-space

  char *p = strchr(rank, toupper(ch)); // Use toupper() to make case insensitive
  if (ch != EOF && p != NULL && *p != '\0') {
    short val = (short) (p - rank + 1);
    if (val != 10) return val;
    ch = fgetc(stdin);
    if (ch == '0') return val;
    val = 1;  // Allow a lone '1' to act like an 'A'
  }

  ungetc(ch, stdin); // Put back unused char for next IO function
  return val;
}

Comments

0

I'm trying to put it in an integer variable called "_val1". This work for any number from 0 to 10. I expected that if I typed a letter, _val1 would get the ASCII value of that character (wich I could use later for my pourposes). But instead _val1 geta value '0' and the letter is automatically passed to my next variable call (wich is _naipe1)

The problem is that the %d conversion specifier only recognizes strings of decimal digits (with an optional leading + or -) and will stop reading at the first non-digit character; if you type in something other than a digit, then the input operation will fail and that character will be left in the input stream.

Your best bet is to read your input as text, then convert it to a numerical value manually, something like the following:

#include <ctype.h>
#include <stdlib.h>

/**
 * Reads a card's face value (2-10,J,Q,K,A) from standard input
 * Returns 0 on error
 */
short get_card_value( void )
{
  char buf[4];  // large enough to hold a 2-digit string plus newline plus 0 terminator
  short val = 0;

  if ( fgets( buf, sizeof buf, stdin ) != NULL )
  {
    char *chk;
    short tmp = (short) strtol( buf, &chk, 0 ); 

    if ( isspace( *chk ) || *chk == 0 )
    {
      if ( tmp >= 2 && tmp <= 10 )
        val = tmp;
    }
    else
    {
      switch( tolower( *chk ) )
      {
        case 'j': val = 11; break;
        case 'q': val = 12; break;
        case 'k': val = 13; break;
        case 'a': val = 11; break;
        default: break;
      }
    }
  }
  // else read error

  return val;
}        

You'd call this as

val1 = get_card_value();
if ( val1 == 0 )
   // error on input

This code doesn't do any length checking on input, so if you enter a card value of 1234567890, that won't be handled gracefully.

Don't use leading underscores in your variable names; names with leading underscores are reserved for the implementation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.