在C-中输入字符到数组中

时间:2009-06-26 15:09:34

标签: c

这是我之前提出的关于计算直手的问题的后续问题......不完全一样......这是读卡的方法 - 它有效 - 但是有更好的方法吗?这在C ...中使用控制台输入

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

我知道案例陈述可以有一些优化 - 即。使用toupper;更好地代表卡片价值等。建议 - 请。代码反映了C99 ......

4 个答案:

答案 0 :(得分:1)

代码看起来很好。在我看来,它实际上做得很好,可读。

您似乎在询问优化问题 - 在您确定需要优化之前不要担心优化,否则它只会使您的代码不易清晰且更容易出错。特别是,这个函数在等待用户输入时运行的时间超过99.99%,因此无需对其进行优化。

我认为使用直通来捕获switch语句中的大写和小写输入并不一定是坏事,特别是在你拥有的情况下。这只是打字的一点点。

如果这段代码确实存在问题并且没有编译或没有按照预期进行操作,请说明问题。

编辑:你可能想要改变的唯一一件事是摆脱0-9级别的明确案例,而是将它们全部合并为一个与案件的案例:

rank = rank_ch - '0';

这是一个相对常见的C语言,用于将存储为字符的数字转换为整数,因此对于阅读它的其他程序员来说,它应该是清晰的。

答案 1 :(得分:1)

我会考虑使用scanf(“%s”,str) - http://www.cplusplus.com/reference/clibrary/cstdio/scanf,而不是使用getchar()。然后,您可以将结果存储在字符数组中,并循环遍历数组,并将字符与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
}

答案 2 :(得分:0)

取决于您使用它的方式以及您希望如何输入数据。如果您想一次输入一张卡片,您可以坚持使用您的方法(或方法,如果您想让它更容易阅读)或使用其他方式,如获取。如果您想要用手阅读,可以将用户输入卡用空格或逗号分隔。然后,只需读取字符串并验证输入。

答案 3 :(得分:0)

代码看起来不错,所以我只有一些小建议:

  • 在他们进入排名后提示用户提供诉讼,只是为了让他们真正明白他们想要做什么。

  • 然后立即检查非法排名,然后告诉用户,而不是等待他们输入诉讼。

  • 鉴于您只想要用户使用2个字符,为什么要等待\ n或任何字符?只需输入2个字符即可继续。

  • 纯粹为了提高可读性,请使用套装的枚举,而不是数字。如果这是扑克(事实上,许多其他纸牌游戏,虽然不是桥牌),无论如何,诉讼的顺序是无关紧要的。

  • 我同意其他关于从字符转换为枚举的评论(rank =(rank_ch - '0') - 2)。不过,在这种有限的情况下,我不会为toupper而烦恼。