2016-10-01 21 views
-1

私はCでジャンケンプログラムを実行するときに、重複ループを得続ける:意図しないループ(C)

#include <stdio.h> 
#include <stdlib.h> 


int getUserInput(userInput); 
int getComputerInput(cpuInput); 
int pickWinner(int player, int cpu); 


int main() 
{ 

    int playerWins = 0; 
    int compWins = 0; 
    int ties = 0; 

    int userInput; 
    int cpuInput; 
    int userChoice =1; 
    int compChoice; 
    int decision; 

while (userChoice != 4) 
{ 

    compChoice = getComputerInput(); 
    userChoice = getUserInput(userInput); 

    printf("computer chose %d\n", compChoice); //for debugging 
    printf("you chose %d \n", userChoice);//for debugging 

    decision = pickWinner(userChoice, compChoice); 

    if (decision == 1) 
    { 
     playerWins++; 
    } 
    else if (decision == 2) 
    { 
     compWins++; 
    } 
    else if (decision == 3) 
    { 
     ties++; 
    } 


} 
    printf("Final score is: \nPLAYER: %d \nCOMPUTER: %d \n", playerWins, compWins); 






} 

//generates a random number for computer, 1=rock 2= paper 3=scissors 
int getComputerInput (int cpuInput) 
{ 

    srand(time(NULL)); 
    int r = rand() %3 +1; 
    return r; 
} 

//prompts user for character input, then converts input into a number to return back to main 
int getUserInput(userInput) 
{ 
    char playerPick ; 


     printf("Please choose R, P, or S. (Q for quit)\n"); 

     playerPick = getchar(); 



      switch(playerPick) 
      { 

       case 'R' | 'r': 
        printf("Player chose R. \n"); 
        return 1; 
        break; 

       case 'p': 
       case 'P': 
        printf("Player chose P. \n"); 
        return 2; 
        break; 

       case 's': 
       case 'S': 
        printf("Player chose S. \n"); 
        return 3; 
        break; 

       case 'q': 
       case 'Q': 
        printf("player quit"); 
        return 4; 
        break; 

       default: 
        printf("Invalid choice, choose again \n"); 
        break; 

      } 




} 
//method for determining winner 
int pickWinner(int player, int cpu) 
{ 
    if (player ==1 && cpu ==1) 
    { 
     printf("tie\n\n"); 
     return 3; 

    } 

    else if (player==1 && cpu ==2) 
    { 
     printf("you lose, paper beats rock\n\n"); 
     return 2; 
    } 

    else if (player ==1 && cpu ==3) 
    { 
     printf("you win, rock beats scissors\n\n"); 
     return 1; 
    } 

    else if (player ==2 && cpu ==1) 
    { 
     printf("you win, paper beats rock\n\n"); 
     return 1; 
    } 

    else if (player ==2 && cpu ==2) 
    { 
     printf("tie\n\n"); 
     return 3; 
    } 
    else if (player ==2 && cpu ==3) 
    { 
     printf("you lose, scissors beats paper\n\n"); 
     return 2; 
    } 

    else if (player ==3 && cpu ==1) 
    { 
     printf("you lose, rock beats scissors\n\n"); 
     return 2; 
    } 

    else if (player ==3 && cpu ==2) 
    { 
     printf("you win, scissors beat paper\n\n"); 
     return 1; 
    } 

    else if (player ==3 && cpu ==3) 
    { 
     printf("tie\n\n"); 
     return 3; 
    } 
} 

出力:

enter image description here

それがゼロバックを渡しているように見えますgetUserInputメソッドに渡すと、私はなぜそれがわかりません。

正しい方向のヒントは非常に高く評価されます。

この投稿が正しくフォーマットされていないとお詫び申し上げます。あなたが入力を入力すると、事前

+1

'case 'R' | 'r': ' - >' case 'R':case 'r': ' –

+0

Cは_methods_をサポートしていません。 _functions_のみ – Olaf

+0

テキストの画像を投稿しないでください! – Olaf

答えて

0

おかげで、あなたは Enterキーを押して入力を終了します。そのキーは実際に改行として入力キューに入れられます。

最初の文字を読むと、入力された文字が表示されます(たとえば、'r')。しかし、入力キュー内の次の文字は改行であり、それはgetcharの2番目の呼び出しが与えるものになります。

これをスキップする方法があります。最も簡単なのは、次の文字を破棄するために余分にgetcharコールを実行することです。しかし、それが改行でない場合(例えば、ユーザーが入力として複数の文字を入力した場合)、それは動作しません。

もう1つの解決策は、fgetsを使用して行全体を読み取って、その行から最初の文字を取得することです。問題は、行を格納するのに十分な大きさのバッファを用意していないと、前と同じ問題が発生することです。

唯一の安全な解決策は、ユーザーからの入力を文字として読み取ることです。その後、改行文字を取得するまでループを読み込みます。ループで読み込んだ文字は、単に破棄されます。この機能のように、おそらく

何か:

playerPick = getchar(); 
skip_past_newline(); 

としてskip_past_newline機能で物事のカップルを注意してください:

void skip_past_newline(void) 
{ 
    int c; 

    while ((c = getchar()) != '\n' && c != EOF) 
    { 
     // Do nothing 
    } 
} 

それからちょうどあなたがユーザーの入力を読んだ後、それを呼び出します上に提示された:

  1. getcharの結果を受け取る変数は、intの変数です。これは実際に重要です。

  2. 私はループ内の改行をチェックするだけでなく、EOFもチェックします。これは、使用されたファイルの終了キーの組み合わせ(WindowsコンソールウィンドウでCtrl-Z)を押したことを示し、プログラムを終了する必要があります。このチェックは、変数をintにする必要がある理由です。

0

AFAICS再び尋ねるコード周りにループが存在しないため、ユーザは、値なしで無効な選択で、getUserInputリターンを入力すると、getUserInput()

  • と、少なくとも2つの問題があります。私はかなり確信しています、コンパイラはこれについて警告します。
  • 値を入力するには、ユーザーは文字と改行を入力する必要があります。これは、2回目に読み込まれた文字で、出力「無効な選択」が生成されます。これを防ぐには、次の入力文字を読み込む前に空白をスキップする必要があります。
関連する問題