2017-01-13 1 views
-2

이것은 내 tic tac toe 프로그램의 accept 함수이므로 s은 데이터를 String 형식과 0,0 또는 2,2 사이에만 저장합니다. p에 값을 저장하려고 할 때Character.getNumericValue를 사용하는 경우 StringIndexOutOfBoundsException

, 지금은 각각 pq의 숫자를 저장하기 위해 getNumericValue 기능을 사용하고 있지만, 런타임 중에, 나는 StringIndexOutOfBounds 예외를 얻을. 선택() 함수는 다른 사람이 벌금을 실행중인) × 결정 또는 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과 같은 값을 두 개의 개별 변수 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() 방법은 다음과 같이해야한다. 이렇게하면 코드의 가독성이 향상됩니다.

관련 문제