Kaiser
Kaiser

Reputation: 35

How to get a character ASCII value in a integer variable?

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);

Upvotes: 1

Views: 13290

Answers (5)

ryyker
ryyker

Reputation: 23218

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
};  

Upvotes: 1

John Bode
John Bode

Reputation: 123468

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.

Upvotes: 0

chux
chux

Reputation: 153508

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;
}

Upvotes: 0

Tanner
Tanner

Reputation: 430

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");
   }
}

Upvotes: 0

zmo
zmo

Reputation: 24812

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;
    }
}

Upvotes: 1

Related Questions