使用Character.getNumericValue时的StringIndexOutOfBoundsException

时间:2017-01-13 08:07:25

标签: java runtime-error stringindexoutofbounds

这是我的tic tac toe程序的accept函数,因此s只会以String格式存储数据,并且在0,0或2,2之间。

我现在使用getNumericValue函数分别在pq中存储数字,但在运行时,我在尝试存储时遇到StringIndexOutOfBounds异常p中的值。

  

只有当choice()函数决定x或O时才会出现问题   在accept()之前被调用,否则它运行正常。 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 个答案:

答案 0 :(得分:1)

你的问题是:

这是我的tic tac toe程序的接受函数,所以s只会以格式存储数据,并且在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倍的时间;并且你用那些丑陋的单字符名称大大增加了愚蠢的拼写错误的可能性!

答案 1 :(得分:0)

如果您只是尝试将0,01,1等值存储在两个单独的int变量中,那么这应该是一个简单的过程。您应该对错误的输入采取预防措施。 因此,您的accept()方法应该是这样的:

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正确提到的那样,你应该为变量使用专有名称。这提高了代码的可读性。

答案 2 :(得分:0)

嘿,我终于在代码中发现了问题。 choice()函数接受一个字符,但是在接受字符串之后,而不是让用户有机会输入字符串,机器自动将null作为输入字符串(在字符后按空格时产生)。

只要在CHAR之后尝试接受字符串或任何其他数据类型,就会产生此问题。

我也找到了解决这个问题的方法。 :)

private static void WriteHeaders(HttpRequestBase request, StringWriter writer)
    {
        foreach (string key in request.Headers.AllKeys)
        {
            writer.WriteLine(string.Format("{0}: {1}", key, request.Headers[key]));
        }

        writer.WriteLine();

        foreach (string key in request.Params.AllKeys)
        {
            writer.WriteLine(string.Format("{0}: {1}", key, request.Params[key]));
        }
        writer.WriteLine();
    }