2017-04-02 12 views
1

私はいくつかのCプログラミングの質問を通じてつもりだと私は現在、ポインタ関連の質問にこだわって追加値 - ポインタと構造を持つ

Q:二次元の値を取る関数を書きますカードブラックジャックハンドを入力とし、ハンドのポイント合計を返します。カード '2'から '9'の値 は額面の値に等しく、カード 'T'、 'K'、 'Q'、 'J'は10ポイントの価値があり、エース( 'A')は別のエースが付いていない限り、11ポイントの価値がある 、その2番目のエースは1ポイントの価値があります。プログラムは誤った入力を捕らえることができるはずです。

例: カードを入力します:AQ スコアはカードを21

入力された:AA はスコアが12

である私は前にこの質問に取り組んできましたが、今回は私が使用する必要があるだろう私はまだかなり新しい方向へ向いています。カード値の取得とカードの計算は、1つの機能で行う必要があります。ここで私はこれまで持っているものです。

#include <stdio.h> 
#define HAND 2 
struct player_hand 
{ 
    char card1; 
    char card2; 
}; 


void getHandValue(struct player_hand * hnd_ptr, char size, char size2) 
{ 
    int first_card; 
    int second_card; 

    //get cards from user 
    scanf("%c %c",&hnd_ptr->card1, &hnd_ptr->card2); 
    printf("Enter Cards: %c %c", &hnd_ptr->card1, &hnd_ptr->card2); 

    //check value of first card in hand 
    if(hnd_ptr->card1<='9' && hnd_ptr->card1>='2') 
    { 
     first_card=(int)hnd_ptr->card1 -48; 

    } 
    //check for special cards: king, queen, jack, ten 
    else if(hnd_ptr->card1=='T'||hnd_ptr->card1=='K'||hnd_ptr->card1=='Q'||hnd_ptr->card1=='J') 
    { 
     first_card=10; 
    } 
    //if first card is Ace 
    else if(hnd_ptr->card1=='A') 
    { 
     first_card=11; 
    } 
    else 
    { 
     //card not valid 
     printf("Not a valid card: %c",hnd_ptr->card1); 
     return; 
    } 

    //check value of 2nd card 
    if(hnd_ptr->card2<='9' && hnd_ptr->card2>='2') 
    { 
     second_card=(int)hnd_ptr->card2 -48; 

    } 
    //if 2nd card is a special kind 
    else if(hnd_ptr->card2=='T'||hnd_ptr->card2=='K'||hnd_ptr->card2=='Q'||hnd_ptr->card2=='J') 
    { 
     second_card=10; 
    } 
    //if 2nd card is Ace 
    else if(hnd_ptr->card2=='A') 
    { 
     if(hnd_ptr->card1=='A') 
     second_card=1; 
     else 
     second_card=11; 
    } 
    else 
    { 
     //if 2nd card not valid 
     printf("Not a valid card: %c",hnd_ptr->card2); 
     return; 
    } 

    add cards 
    printf("\nThe total card value is: %d",first_card+second_card); 

} 

//call function, test if works 
//calling it wrong? 
int main(void) 
{ 
    struct player_hand hnd [HAND] = { {'A', 'A'}}; 
    getHandValue (hnd, HAND); 
    return; 
} 
+0

あなたは今直面している問題は何ですか? –

+0

ポインタを構造体に渡している場合、手の引数を取る必要はありません。ポインタを使用してアクセスできます。 –

答えて

2

あなたにはいくつかのバグがあります。

mainの間違った呼び出し。

この関数はsize引数を必要とせず、それが行われた場合はintである必要があります。

不良returnmainから。

この機能では、printfが間違っています。

structは配列の代わりに2つのスカラーを使用するため、状況ははるかに複雑になります。

私はあなたのプログラムの2つのバージョンを作成しました。 1つはバグの注釈付きです。物事をきれいにするものもあります。

ここで注釈付きバージョンです:

#include <stdio.h> 

#define HAND 2 

struct player_hand { 
    char card1; 
    char card2; 
}; 

// NOTE/BUG: use 'int' for size and size2 
void 
getHandValue(struct player_hand *hnd_ptr, char size, char size2) 
{ 
    int first_card; 
    int second_card; 

    // get cards from user 
    scanf("%c %c", &hnd_ptr->card1, &hnd_ptr->card2); 

// NOTE/BUG: this would print the _address_ of the values vs. the values 
    printf("Enter Cards: %c %c", &hnd_ptr->card1, &hnd_ptr->card2); 

// NOTE/BUG [sort of]: the code below is cut-n-paste replication because you 
// have separate card1 and card2 in the struct -- this "cries out" for an 
// array and a loop. Consider the general case where you have 5 cards in the 
// hand (e.g. five card charlie). The code would be easier even with an array 
// of only two 

    // check value of first card in hand 
    if (hnd_ptr->card1 <= '9' && hnd_ptr->card1 >= '2') { 
     first_card = (int) hnd_ptr->card1 - 48; 

    } 
    // check for special cards: king, queen, jack, ten 
    else if (hnd_ptr->card1 == 'T' || hnd_ptr->card1 == 'K' || hnd_ptr->card1 == 'Q' || hnd_ptr->card1 == 'J') { 
     first_card = 10; 
    } 
    // if first card is Ace 
    else if (hnd_ptr->card1 == 'A') { 
     first_card = 11; 
    } 
    else { 
     // card not valid 
     printf("Not a valid card: %c", hnd_ptr->card1); 
     return; 
    } 

    // check value of 2nd card 
    if (hnd_ptr->card2 <= '9' && hnd_ptr->card2 >= '2') { 
     second_card = (int) hnd_ptr->card2 - 48; 

    } 
    // if 2nd card is a special kind 
    else if (hnd_ptr->card2 == 'T' || hnd_ptr->card2 == 'K' || hnd_ptr->card2 == 'Q' || hnd_ptr->card2 == 'J') { 
     second_card = 10; 
    } 
    // if 2nd card is Ace 
    else if (hnd_ptr->card2 == 'A') { 
     if (hnd_ptr->card1 == 'A') 
      second_card = 1; 
     else 
      second_card = 11; 
    } 
    else { 
     // if 2nd card not valid 
     printf("Not a valid card: %c", hnd_ptr->card2); 
     return; 
    } 

    printf("\nThe total card value is: %d", first_card + second_card); 
} 

//call function, test if works 
//calling it wrong? 
int 
main(void) 
{ 

// NOTE: based on usage, this is only an array because you're not using &hnd 
// below 
    struct player_hand hnd[HAND] = { 
     {'A', 'A'} 
    }; 

// NOTE/BUG: too few arguments to function, but why pass count at all? 
    getHandValue(hnd, HAND); 

// NOTE/BUG: need to return value (e.g. return 0) 
    return; 
} 

ここでクリーンアップバージョンです:他の回答に加えて、あなたの目的は2手に合格することでした、場合

#include <stdio.h> 

#define CARDS_PER_HAND  2 

struct player_hand { 
    char card[CARDS_PER_HAND]; 
}; 

void 
getHandValue(struct player_hand *hnd_ptr) 
{ 
    int idx; 
    int card; 
    int sum; 
    int count[CARDS_PER_HAND]; 

    // get cards from user 
    printf("Enter Cards:"); 
    fflush(stdout); 
    for (idx = 0; idx < CARDS_PER_HAND; ++idx) 
     scanf(" %c", &hnd_ptr->card[idx]); 

    // print cards 
    printf("Cards entered:"); 
    for (idx = 0; idx < CARDS_PER_HAND; ++idx) 
     printf(" %c", hnd_ptr->card[idx]); 
    printf("\n"); 

    for (idx = 0; idx < CARDS_PER_HAND; ++idx) { 
     card = hnd_ptr->card[idx]; 

     // simple cards 
     if (card <= '9' && card >= '2') { 
      count[idx] = (card - '2') + 2; 
      continue; 
     } 

     switch (card) { 
     case 'A': 
      count[idx] = 11; 
      if ((idx == 1) && (count[0] == 11)) 
       count[idx] = 1; 
      break; 

     case 'T': 
     case 'K': 
     case 'Q': 
     case 'J': 
      count[idx] = 10; 
      break; 

     default: 
      printf("Not a valid card: %c", card); 
      return; 
      break; 
     } 
    } 

    sum = 0; 
    for (idx = 0; idx < CARDS_PER_HAND; ++idx) 
     sum += count[idx]; 

    printf("The total card value is: %d\n", sum); 
} 

int 
main(void) 
{ 
    struct player_hand hnd; 

    getHandValue(&hnd); 

    return 0; 
} 
+0

ええ、ありがとう!私はあなたのコードを見て、それを勉強します。本当にポインタのハングアップを取得したいのですが、少し難しいです。 – supperforpupper

+0

あなたは大歓迎です!私が推測する重要なポイントは、言い回しの複製がたくさんあるように見える(つまり、 'card = hnd_ptr-> card [idx]'によって簡略化された 'card 'ループ)またはコードの複製[同じコードが各カードごとに別々に記載されている]は、アーキテクチャをリファクタリングする必要があることを示しています。より多くの経験を積むことで、最初のコーディング中にこれらの単純化を見つけることができますが、自分自身を「コーナーに描く」ことがわかった場合は、停止して息を吐き、物事を再現することができます。 –

0

あなたが機能getHandValue()hndのアドレスを渡していません。これを行うには、&オペレーターgetHandValue(&hnd)を使用して住所を渡す必要があります。

struct player_hand hndも正しく初期化されていません。 {}のセットが1つ多くあります。

0

ここでは、編集したmain()コードのコードを示します。ポインタの設定方法を少し変更するだけです。

// main 
int main(void) 
{ 
    // minor edits to fix the code here 
    struct player_hand hnd = {'A', 'A'}; 
    struct player_hand *hndPtr = &hnd; 

    getHandValue (hndPtr); 
    return 0; 
} 
0

は、配列では、スコアリング関数のループ内で両手を処理する必要があります。たとえば、次のように

#include <stdio.h> 

#define HAND 2 

struct player_hand 
{ 
    char card1; 
    char card2; 
}; 

void getHandValue (struct player_hand *hnd_ptr, int size) 
{ 
    int first_card; 
    int second_card; 

    /* get cards from user */ 
    for (int i = 0; i < size; i++) { 
     printf ("\nenter cards for hand %d (card1 card2): ", i); 

     /* you must handle the '\n' that remains after last char */ 
     if (scanf ("%c %c%*c", &hnd_ptr[i].card1, &hnd_ptr[i].card2) != 2) { 
      fprintf (stderr, "error: invalid entry.\n"); 
      return; 
     } 
     printf ("you entered: %c %c\n", hnd_ptr[i].card1, hnd_ptr[i].card2); 
    } 

    for (int i = 0; i < size; i++) 
    { 
     /* check value of first card in hand */ 
     if(hnd_ptr[i].card1 <= '9' && hnd_ptr[i].card1 >= '2') 
     { 
      first_card = (int)hnd_ptr[i].card1 - '0'; 

     } 
     /* check for special cards: king, queen, jack, ten */ 
     else if (hnd_ptr[i].card1 == 'T' || hnd_ptr[i].card1 == 'K' || 
       hnd_ptr[i].card1 == 'Q' || hnd_ptr[i].card1 == 'J') 
     { 
      first_card = 10; 
     } 
     /* if first card is Ace */ 
     else if (hnd_ptr[i].card1 == 'A') 
     { 
      first_card = 11; 
     } 
     else 
     { 
      /* card not valid */ 
      printf("Not a valid card: %c",hnd_ptr[i].card1); 
      return; 
     } 

     /* check value of 2nd card */ 
     if(hnd_ptr[i].card2 <= '9' && hnd_ptr[i].card2 >= '2') 
     { 
      second_card=(int)hnd_ptr[i].card2 - '0'; 

     } 
     /* if 2nd card is a special kind */ 
     else if (hnd_ptr[i].card2 == 'T' || hnd_ptr[i].card2 == 'K' || 
       hnd_ptr[i].card2 == 'Q' || hnd_ptr[i].card2 == 'J') 
     { 
      second_card = 10; 
     } 
     /* if 2nd card is Ace */ 
     else if (hnd_ptr[i].card2 == 'A') 
     { 
      if (hnd_ptr[i].card1 == 'A') 
       second_card = 1; 
      else 
       second_card = 11; 
     } 
     else 
     { 
      /* if 2nd card not valid */ 
      printf ("Not a valid card: %c", hnd_ptr[i].card2); 
      return; 
     } 

     /* add cards */ 
     printf ("\nThe total cards value (hand %d) is: %d\n", 
       i, first_card + second_card); 
    } 
} 

int main(void) 
{ 
    struct player_hand hnd[HAND] = { {'A', 'A'}, {'A', 'A'} }; 
    getHandValue (hnd, HAND); 

    return 0; 
} 

使用例/出力

$ ./bin/cards 

enter cards for hand 0 (card1 card2): A A 
you entered: A A 

enter cards for hand 1 (card1 card2): 8 K 
you entered: 8 K 

The total cards value (hand 0) is: 12 

The total cards value (hand 1) is: 18 

あなたの目的は、構造体の配列を渡すことではなかった場合は、明らかにループが必要ではないでしょう。注:2つのループが使用されました。最初は両手用のカードを取得し、2番目のカードは両者のスコアを計算します。 (あなたは1つでそれをすることができましたが、得点する前にすべてのカードを入力したかのように見えました)事柄を見て、さらに質問があれば教えてください。

関連する問題