2009-06-26 9 views
2

Ceci est une question complémentaire à une question précédente que j'ai posée au sujet du calcul d'une main droite ... pas exactement la même chose ... C'est la méthode à lire dans les cartes-cela fonctionne- mais est-il une meilleure Way- de le faire en utilisant l'entrée de la console en C ...Saisie de caractères dans les tableaux en C- suivi

void read_cards(int num_in_rank[], int num_in_suit[]) 
{ 
    bool card_exists[NUM_RANKS][NUM_SUITS]; 
    char ch, rank_ch, suit_ch; 
    int rank, suit; 
    bool bad_card; 
    int cards_read = 0; 

    for (rank = 0; rank < NUM_RANKS; rank++) { 
    num_in_rank[rank] = 0; 
    for (suit = 0; suit < NUM_SUITS; suit++) 
     card_exists[rank][suit] = false; 
    } 

    for (suit = 0; suit < NUM_SUITS; suit++) 
    num_in_suit[suit] = 0; 

    while (cards_read < NUM_CARDS) { 
    bad_card = false; 

    printf("Enter a card: "); 

    rank_ch = getchar(); 
    switch (rank_ch) { 
     case '0':   exit(EXIT_SUCCESS); 
     case '2':   rank = 0; break; 
     case '3':   rank = 1; break; 
     case '4':   rank = 2; break; 
     case '5':   rank = 3; break; 
     case '6':   rank = 4; break; 
     case '7':   rank = 5; break; 
     case '8':   rank = 6; break; 
     case '9':   rank = 7; break; 
     case 't': case 'T': rank = 8; break; 
     case 'j': case 'J': rank = 9; break; 
     case 'q': case 'Q': rank = 10; break; 
     case 'k': case 'K': rank = 11; break; 
     case 'a': case 'A': rank = 12; break; 
     default:   bad_card = true; 
    } 

    suit_ch = getchar(); 
    switch (suit_ch) { 
     case 'c': case 'C': suit = 0; break; 
     case 'd': case 'D': suit = 1; break; 
     case 'h': case 'H': suit = 2; break; 
     case 's': case 'S': suit = 3; break; 
     default:   bad_card = true; 
    } 

    while ((ch = getchar()) != '\n') 
     if (ch != ' ') bad_card = true; 

    if (bad_card) 
     printf("Bad card; ignored.\n"); 
    else if (card_exists[rank][suit]) 
     printf("Duplicate card; ignored.\n"); 
    else { 
     num_in_rank[rank]++; 
     num_in_suit[suit]++; 
     card_exists[rank][suit] = true; 
     cards_read++; 
    } 
    } 
} 

Je sais que la déclaration de cas peut avoir quelques optimisations à savoir utilisant toupper; meilleure représentation des valeurs de la carte, etc .. Suggestions - s'il vous plaît. Le code est réfléchissant de C99 ...

+0

Pourriez-vous clarifier la question un peu? J'ai un peu de mal à comprendre ce que tu demandes. Cela pourrait juste être moi cependant. –

Répondre

1

Le code me semble bien. C'est en fait assez bien fait et lisible à mon avis.

Il semble que vous vous posiez des questions sur les optimisations - ne vous inquiétez pas de l'optimisation tant que vous n'êtes pas sûr d'en avoir besoin, sinon cela rend votre code moins lisible et plus vulnérable aux bogues. En particulier, cette fonction va passer plus de 99,99% du temps qu'elle est en train d'être exécutée en attendant que l'utilisateur tape, il n'est donc pas nécessaire de l'optimiser.

Je ne pense pas qu'il soit nécessairement mauvais d'utiliser la fonction d'accès direct pour capturer les entrées majuscules et minuscules dans une instruction switch, surtout avec le moins de cas possible. C'est juste un peu plus de frappe.

S'il y a réellement un problème avec ce code et qu'il ne compile pas ou ne fait pas ce qu'il est censé faire, décrivez le problème.

Edit: La seule chose que vous voudrez peut-être changer est de se débarrasser des cas explicites pour les rangs 0-9, et au lieu de les combiner en une seule chute par cas avec le corps:

rank = rank_ch - '0'; 

C'est un langage C relativement commun pour convertir un nombre stocké comme un caractère en entier, il devrait donc être lisible par d'autres programmeurs qui le lisent.

+0

Merci pour l'entrée ici ... – iwanttoprogram

0

Dépend de l'utilisation que vous en faites et de la façon dont vous voulez entrer les données. Si vous voulez entrer une carte à la fois, vous pouvez vous en tenir à votre méthode (ou à vos méthodes, si vous voulez la rendre plus facile à lire) ou utiliser une autre méthode comme get. Si vous cherchez à lire dans les mains, vous pouvez avoir les cartes d'entrée utilisateur séparées par des espaces ou des virgules. Ensuite, lisez simplement la chaîne et validez l'entrée.

1

Plutôt que d'utiliser getchar(), je considérerais d'utiliser scanf ("% s", str) - http://www.cplusplus.com/reference/clibrary/cstdio/scanf. Vous pouvez ensuite stocker les résultats dans un tableau de caractères, et faire une boucle dans le tableau et comparer les caractères à leurs valeurs hexadécimales ou décimales corrospondantes sur le tableau ascii http://www.s4a.us/support/images/ascii_chart.gif.

int rank = 0; 
int suite = 'c'; 
char[3] buff; // be careful of overflow 
printf ("Enter the rank and suite: "); 
scanf ("%s",buff); 

for(int i=0; i<2; i++) 
{ 
    // compare elements of buff to those in the ascii chart 
} 
+1

Je considérerais cela trop compliqué, puisque vous ne traitez que deux caractères, traités séparément et différemment. Il n'y a aucune raison de s'inquiéter des tampons et des débordements et des boucles dans cette partie du code. De plus, le code que vous avez publié contient déjà un bogue de débordement - il n'y a pas d'espace dans le tableau buff pour le \ 0 final que scanf écrira dans la chaîne. –

+1

Vous avez raison. Il vaudrait mieux utiliser scanf ("% c"). Je pense toujours que l'utilisation du tableau Ascii réduirait considérablement la taille du code. – dacman

+0

Je ne suis pas sûr de ce que vous voulez dire par tableau ASCII. Suggérez-vous que comparer rank_ch à 84 est plus rapide que de le comparer à 'T'? Ce n'est pas le cas, et ce dernier est beaucoup plus lisible. –

0

Le code semble OK pour moi, donc je mineures suggestions:

  • Demander à l'utilisateur pour le costume après qu'elles sont entrées dans le rang, juste pour faire ce qui est vraiment évident qu'ils Je suppose être en train de faire. Après cela, vérifiez immédiatement un rang illégal et parlez-en à l'utilisateur, plutôt que d'attendre qu'ils entrent dans la combinaison.

  • Étant donné que vous attendez seulement 2 caractères de l'utilisateur, pourquoi attendre \ n ou des caractères? Continuez simplement une fois que 2 caractères ont été entrés. Pour des raisons de lisibilité, utilisez un enum pour les combinaisons, plutôt que des chiffres.Si c'est pour le poker (et en effet, beaucoup d'autres jeux de cartes, mais pas de bridge), l'ordre des costumes est irrevelevant de toute façon.

  • Je suis d'accord avec d'autres commentaires à propos de la conversion des caractères en enums (rank = (rank_ch - '0') - 2). Je ne voudrais pas déranger avec toupper dans un tel cas limité, cependant.

Questions connexes