代码之家  ›  专栏  ›  技术社区  ›  iwanttoprogram

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

c
  •  2
  • iwanttoprogram  · 技术社区  · 17 年前

    这是上一个关于计算直手的问题的后续问题…不完全相同…这是在卡片中读取的方法-有效-但有更好的方法-使用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++;
        }
      }
    }
    

    我知道case语句可以有一些优化,例如使用toupper;更好地表示卡值等。建议-请。代码反映了C99…

    4 回复  |  直到 17 年前
        1
  •  1
  •   Tyler McHenry    17 年前

    我觉得这个密码不错。在我看来,它实际上做得很好,可读性也很强。

    似乎你在问优化问题——在确定你需要它之前,不要担心优化,否则它只会使你的代码不那么清晰,更容易出错。特别是,这个函数将花费99.99%以上的时间运行,只是等待用户输入,所以不需要优化它。

    我认为使用fall-through捕获switch语句中的大小写输入并不一定是坏事,尤其是在很少的情况下。只是多打了一点。

    如果这段代码实际上有问题,并且它没有编译或者没有做它应该做的事情,请描述这个问题。

    编辑:您可能要更改的唯一一件事是去掉0-9列的显式事例,而是将它们全部合并为一个贯穿事例和正文:

    rank = rank_ch - '0';
    

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

        2
  •  1
  •   dacman    17 年前

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

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

        4
  •  0
  •   Steve Melnikoff    17 年前

    代码对我来说没问题,所以我只有一些小建议:

    • 在用户进入等级后提示他们购买西服,只是为了让他们真正明白他们应该做什么。

    • 从那以后,立即检查一个非法的排名,然后告诉用户,而不是等待他们进入诉讼。

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

    • 纯粹是为了提高可读性,对西服使用枚举,而不是数字。如果这是为扑克(实际上,许多其他的纸牌游戏,虽然不是桥牌),秩序的西装是不敬的无论如何。

    • 我同意其他有关从chars转换为enums(rank=(rank_ch-“0”)-2的意见。不过,在这样一个有限的情况下,我不想麻烦图珀。