2017-01-13 1 views
-2

これはtic tac toeプログラムのaccept関数です。したがって、sは、データをString形式で、0,0または2,2の間にのみ格納します。 pに値を格納しようとしたときCharacter.getNumericValueを使用しているときのStringIndexOutOfBoundsException

、私は今、それぞれpqに数値を格納するためにgetNumericValue機能を使用していますが、実行時に、私はStringIndexOutOfBounds例外を取得します。

問題は、そうでなければ罰金を実行している)、xまたはO を決定する選択肢()関数は前に(受け入れ呼ばれたときにのみ起こっています。 choice()関数の問題は何ですか?

void accept()throws IOException 
{ 
    System.out.println("Your move:"); 
    String s=xy.readLine(); 

    int p = (Character.getNumericValue(s.charAt(0)))-1; 
    int q = Character.getNumericValue(s.charAt(2))-1; 
    if(ar[p][q]==0) 
     ar[p][q]=1; 
    else 
    { 
     System.out.println("You can't capture a location that has already been captured!"); 
     accept(); 
    } 
} 



void choice() throws IOException 
    { 
     System.out.println("Welcome to tictactoe"); 
     System.out.print("Enter your weapon X or O : "); 
     chp = Character.toUpperCase((char)xy.read()); 

     if (chp=='X') 
      chc='O'; 
     else 
      chc = 'X'; 

     System.out.println("kkbot chose: "+ chc); 
    } 
+3

[ 'String.charAt'のドキュメント](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#charAt(int)を読みます)。渡すインデックスが> = Stringの場合、 'StringIndexOutOfBoundsException'が返されます。言い換えれば、 's'は2文字未満であり、' 2'は無効なインデックスになります。 – qxz

+0

入力形式とは何ですか? –

+0

@ShyamBaitmangalkar String正しい形式で正しい入力を行った後でも、sは何らかの理由で常に空文字列を格納し、Character.getNumericValueは-1を返します。 –

答えて

0

ちょっと私はコードの問題を発見しました。 choice()関数は文字を受け入れますが、文字列を受け入れると、ユーザーに文字列を入力する代わりに、自動的に入力文字列としてNULLが使用されます(文字の後のスペースを押すと生成されます)。

この問題は、CHARの後に文字列またはその他のデータ型を受け入れるたびに生成されます。

私もこの問題をハックする方法を見つけました。 :)

import java.io.*; 
class tictactoe 
{ 
    BufferedReader xy=new BufferedReader(new InputStreamReader(System.in)); 
    void accept()throws IOException 
    { 
     System.out.println("Enter your weapon X or O : "); 
     char ch = xy.readLine().charAt(0); 

     System.out.println("Your move:"); 
     String s=xy.readLine(); 
    } 
} 
1

あなたの問題は、次のとおりです。

は、これは私のチックタックつま先のプログラムなので、秒間受け入れる機能のみ0,0または2の間の形式にしてデータを保存するために起こっているされ、 2。

しかし、その後、あなたのコードではありません:

String s=xy.readLine(); 
int p = (Character.getNumericValue(s.charAt(0)))-1; 
int q = Character.getNumericValue(s.charAt(2))-1; 

は、ユーザーが彼が望んでいるものは何でもを入力することができます。 の中の何もreadLine()は、彼に空の文字列または長すぎる文字列を追加させないでしょう!

あなたはその文字列とを行う前に、あなたはそれが長さを想定していること検証を持っています。以下のように:それを超えて

String inputFromUser = ""; 
do { 
    System.out.println("Your move [enter a value like A1]: "); 
    inputFromUser = scanner.readLine(); 
} while (inputFromUser.length != 2); 

:あなたの変数の本当名を使用してください。 s、xy、p、q ...これらの変数の目的については、読者にはありません。を教えてください。はい、入力中に少し時間を節約できます。後でソースコードを読むときにはその10倍の時間を費やします。それらの醜いシングル文字の名前で愚かなタイプミスの可能性を劇的に高めます!

0

0,0または1,1のような値を2つの別々のint変数に格納しようとしているのであれば、それは単純な処理でなければなりません。あなたは間違った入力に注意を払う必要があります。

public void accept(){ 
     Scanner sc = new Scanner(System.in); 
     System.out.println("Your move [Enter marking position in the form x,y]: "); 
     String userInput = sc.nextLine(); 
     String[] userMarkedPositions = userInput.split(","); 
     if(userMarkedPositions.length == 2){ 
      int x = Integer.parseInt(userMarkedPositions[0]); 
      int y = Integer.parseInt(userMarkedPositions[1]); 
      //Followed by your other operations 
      //.... 
      //.... 
     }else{ 
      System.out.println("Invalid input!!"); 
      System.out.println("Input should be in the form of x,y"); 
      accept(); 
     } 
     sc.close(); 
    } 

そして、ちょうど@GhostCatが正しく言及したように、あなたは、変数のための適切な名前を使用する必要があります: したがって、あなたのaccept()方法は次のようなものでなければなりません。これにより、コードの可読性が向上します。

関連する問題