42

所以,我被这段代码卡住了:

import java.util.InputMismatchException;
import java.util.Scanner;

public class ConsoleReader {

    Scanner reader;

    public ConsoleReader() {
        reader = new Scanner(System.in);
        //reader.useDelimiter(System.getProperty("line.separator"));
    }

    public int readInt(String msg) {
        int num = 0;
        boolean loop = true;

        while (loop) {
            try {
                System.out.println(msg);
                num = reader.nextInt();

                loop = false;
            } catch (InputMismatchException e) {
                System.out.println("Invalid value!");
            } 
        }
        return num;
    }
}

这是我的输出:

插入一个整数:
无效值!
插入一个整数:
无效值!
...

4

5 回答 5

70

根据扫描仪的javadoc

当扫描器抛出 InputMismatchException 时,扫描器不会传递导致异常的令牌,以便可以通过其他方法检索或跳过它。

这意味着如果下一个标记不是int,它会抛出InputMismatchException,但标记会保留在那里。因此,在循环的下一次迭代中,reader.nextInt()再次读取相同的标记并再次引发异常。你需要的是用完它。reader.next()在你的里面添加一个catch来消费令牌,它是无效的,需要被丢弃。

...
} catch (InputMismatchException e) {
    System.out.println("Invalid value!");
    reader.next(); // this consumes the invalid token
} 
于 2010-08-26T05:18:59.300 回答
0

我要做的是使用 Scanner.nextLine() 读取整行。然后创建另一个扫描仪来读取返回的字符串。

String line = reader.nextLine();
Scanner sc = new Scanner(line);

这将使您的示例函数如下所示:

  public int readInt(String msg) {
        int num = 0;
        boolean loop = true;

        while (loop) {
            try {
                System.out.println(msg);
                String line = reader.nextLine();
                Scanner sc = new Scanner(line);
                num = sc.nextInt();   
                loop = false;
            } catch (InputMismatchException e) {
                System.out.println("Invalid value!");

            } 
        }
        return num;
    }

这样一来,您就拥有了一台扫描仪来获取输入和一台验证输入,这样您就不必担心读者是否会关心他们是否输入了正确的输入形式。

于 2010-08-26T05:29:08.107 回答
0

你的 while-do 守卫是“循环”变量。

在您的代码到达赋值循环之前引发的异常本身 = false; 准确地说,异常是在前面的语句中抛出的,即 num = reader.nextInt();

当抛出异常时,'loop' 变量的值为 'true' 但你的代码会跳转到 catch 块,然后重复 while-do。这个 while-do 永远不会停止,因为下一次迭代将再次抛出异常,再次跳转到 catch 块等等。

要终止这个 while-do,你需要用另一个逻辑的东西来保护你的 while-do,例如:

  1. 当阅读器获得非整数字符时退出
  2. EOF 时退出

这可以在 catch 块或其他一些行中完成。但精确的解决方案取决于您的规格。

于 2010-08-26T05:34:00.200 回答
0

你也可以试试这个:

   public int readInt(String msg) {
        int num = 0;
        try {
            System.out.println(msg);
            num = (new Scanner(System.in)).nextInt();
        } catch (InputMismatchException e) {
            System.out.println("Invalid value!");
            num = readInt(msg);
        } 
        return num;
    }
于 2010-08-26T05:34:48.967 回答
0
package nzt.nazakthul.app;

import java.util.*;

public class NztMainApp {

    public static void main(String[] args) {
    ReadNumber readObj = new ReadNumber();
    readObj.readNumber();
    }

}

class ReadNumber {
int no;

    int readNumber() {
    Scanner number = new Scanner(System.in);
    int no=0;
    boolean b=true;
    do {

        try {
            System.out.print("Enter a number:\t");
            no = number.nextInt();
        } catch (InputMismatchException e) {
            System.out.println("No Number");
            //e.printStackTrace();

            b=false;
        }

    }

    while (b);
    return no;

    }

}

我个人使用 BufferedReader 和 InputStreamReader 来读取字符串并检查是否是数字,但使用扫描仪的代码更少。代码检查并运行正常。

于 2014-07-23T09:50:16.237 回答