3

我正在尝试使用in.nextLine()和从那里解析控制台输入中的字符 take charAt(0)。我的问题是在要求用户输入字符串以执行in.nextLine()on 之后,它会跳过输入并由于尝试获取空字符串的第一个字符而产生错误。

System.out.print("Select an operator (+, -, *, /), 'c' or 'C' to clear, or 'q' to quit: ");
String temp = in.nextLine();
char tempOperator = temp.charAt(0);

错误是

java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)

完整程序可在此处获得

欢迎提出一般性意见和建议。提前致谢。

4

4 回答 4

4

当您这样做时cValue = in.nextDouble();,它会读取下一个标记(完整值)并将其解析为加倍。如果此时按下回车键,\n是缓冲区中的下一个要读取的令牌。

当你这样做时:String temp = in.nextLine();,它\n从前一个输入的缓冲区中读取并charAt(0)失败,因为它只读取了 empty("") 字符串。

为了克服这个问题,或者通过添加一个附加项来跳过前一个缓冲区in.nextLine(),添加\n \r如下跳过模式(这是在Scanner.classas中定义的模式LINE_SEPARATOR_PATTERN):

 in.skip("\r\n|[\n\r\u2028\u2029\u0085]");

或如下放置一个小循环while

   String temp = "";
   while((temp.length() < 0){
      temp = in.nextLine();
   }
于 2012-10-31T16:10:26.957 回答
1

您可能会考虑的一件事是不要这样做:

String temp = in.nextLine();

做这个:

String temp = in.next();

这当然是假设您只需要用户输入中的一个字符,看起来这就是您要求用户的全部内容。这将消除您收到的异常。但是,如果您想在用户键入多个字符时抛出错误,您可能需要先阅读整行以查看长度是多少。

于 2012-10-31T16:10:06.817 回答
1

好吧,问题出在这条线上in.nextDouble()

Scanner#nextDouble从用户那里读取下一个令牌作为双倍。因此,当您将值4.5作为输入传递时,nextDouble只需读取令牌4.5并跳过linefeed用户输入的输入。现在这个换行(因为这是一个新行),将被视为下一个的输入Scanner.nextLine。因此,您的in.nextLineafterin.nextDouble正在阅读newlineprevious 的剩余内容in.nextDouble

因此,解决方法与@tjg184 在他的回答中指出的相同。in.nextLine之后添加一个空白in.nextDouble将读取newline剩下的内容。因此,您的到来in.nextLine会读取实际传递的输入。

cValue = in.nextDouble();
in.nextLine();  // Add this before your `while` which will read your `newline`

while (true) {
    //continue;
}

然而,Scanner.nextLine读取完整的输入直到换行。因此,它不会留下任何newline供用户下次阅读的内容。

虽然不需要这个答案,但@tjg184's答案是一样的。我刚刚添加它是为了更好地解释到底发生了什么。

于 2012-10-31T16:10:41.820 回答
0

查看您的程序,这是因为String temp = in.nextLine();. 当用户点击“Enter”键时,它本质上是跳过此语句,因为用户键入了“Enter”。试试下面的。注意,我只添加了以下行String enter = in.nextLine();

import java.util.Scanner;

public class Calculator
{    
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        char operator = 'z'; //initialize operator
        double cValue; //current value
        double rhValue; //right hand value
        boolean cont = true;

        System.out.print("Enter starting value: ");
        cValue = in.nextDouble();

        // disregard the "Enter" key
        String enter = in.nextLine();

        while(true)
        {
            System.out.print("Select an operator (+, -, *, /), 'c' or 'C' to clear, or 'q' to quit: ");
            String temp = in.nextLine();
            char tempOperator = temp.charAt(0);

            if (tempOperator == 'c' || tempOperator == 'C')
            {
                cValue = 0.0;
                System.out.println("Current value is: " + cValue);
                System.out.println();
            }
            else if(tempOperator == 'q')
            {
                System.out.println("Final result: " + cValue);
                System.exit(1);
            }
            else if(tempOperator == '+' || tempOperator == '-' || tempOperator == '*' || tempOperator == '/')
            {
                operator = tempOperator;
                break;
            }
            else
                throw new IllegalArgumentException("operator not valid");
        }


        System.out.println("Enter a right hand value (type double): ");
        rhValue = in.nextDouble();

        System.out.println("Math expression: answer " + operator + "= " + rhValue);
        switch(operator)
        {
            case '+': cValue =+ rhValue;
                      break;
            case '-': cValue =- rhValue;
                      break;
            case '*': cValue = cValue * rhValue;
                      break;
            case '/': cValue = cValue / rhValue;
                      break;
        }

        System.out.println("Current value is: " + cValue);
    }
}
于 2012-10-31T15:58:33.653 回答