使用 BufferedReader 时如何避免 NumberFormatException?

How to avoid NumberFormatException while using BufferedReader?

我使用 BufferedReader 从用户那里读取数据,但它给出了 NumberFormat 异常,前提是我以某种方式提供了输入。假设在 C 中,我这样写代码:

scanf("%d %d", &x, &y);

我尝试像这样给控制台输入:23 45,它分配的值是这样的:

x = 23, y = 45

我怎样才能在 java 中做这样的事情。我这样试过:

BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));
String line1 = br1.readLine();
String line2 = br2.readLine();
int x = Integer.parseInt(line1);
int y = Integer.parseInt(line2);

但这给出了:

Exception in thread "main" java.lang.NumberFormatException: For input string: "23 45" at java.lang.NumberFormatException.forInputString(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at AB.main(AB.java:23)

一个InputStreamReader就够了:

   BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
    String line1 = br1.readLine();
    String[] args = line1.split(" ");

    if (args.length != 2) {
        throw new IllegalArgumentException("The input is wrong");
    }

    int x = getIntFromInput(args[0]);
    int y = getIntFromInput(args[1]);

正如 Jan 指出的那样,您将需要一种转换方法:

public static int getIntFromInput(String inputString) {

    //sanity checks
    if (inputString == null || inputString.trim().length() == 0) {
        throw new IllegalArgumentException("empty or null string passed");
    }

    try {
        return new BigInteger(inputString, 10).intValueExact();
    } catch (Exception ignored) {
        throw new IllegalArgumentException(String.format("input string is not a valid integer number: '%s'", inputString));
    }
}

如果您真的想在同一行上传递两个参数,请在空格处拆分该行,然后分别使用每个标记:

BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));

String line1 = br1.readLine();

String[] tokens = line1.split("\s+") 

int x = Integer.parseInt(tokens[0]);
int y = Integer.parseInt(tokens[1]);

readLine() 读取直到出现换行符,通常表示用户按下了回车键。

如果你输入 12 34,这是一行,一行格式不像整数。

您可以使用 read() 一次读取一个字符,手动拆分行并解析结果,或者最好使用 Scanner class。它有一个更面向用户 IO 的 api,暴露了诸如 nextInt()next() 的方法(返回下一个 "token" 而不是下一个字符)等等。

Scanner in = new Scanner(System.in);
int x = in.nextInt();
int y = in.nextInt();

你必须这样做:

String in = *getline*;
String[] tab = in.split(' ');
List<int> nums = new         ArrayList<int>();

for(String a : tab){
nums.add(Integer.parseInt(a));         // or push() not remember...
}

// Your nums have your integers now

这将解决您的问题

int x, y;
String[] input;
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  String str = br.readLine();
  input = str.split(" ");

  x = Integer.parseInt(input[0]);
  y = Integer.parseInt(input[1]);

现在我们到了 - 很多很多答案只是解释如何阅读 正确 输入。但是你会得到 NumberFormatExceptions 任何其他奇怪的方式。就像您的输入是...

98765432109876543210 9876543210987654321 

这又会抛出 NumberFormatException,因为它们太大而无法放入 int

因此,虽然在 " " 处拆分并手动寻址令牌是个好建议,但如果仅 one 给出了号码。

我的建议是在进行任何进一步解析之前检查输入是否有效

Scanner s = new Scanner(System.in);
String line = s.nextLine();
Pattern p = Pattern.compile("(\d{1,10})\s+(\d{1,10})");
Matcher m = p.matcher(line);
if(m.matches()) {
  long x1 = Long.parseLong(m.group(1));
  long y1 = Long.parseLong(m.group(2));
  if(x1 <= Integer.MAX_VALUE&& y1 <= Integer.MAX_VALUE) {   
    int x = (int)x1;
    int y = (int)y1;
    System.out.printf("Your input: %d / %d", x, y);
  } else {
    System.err.println("Numbers too big");
  }
} else {
  System.err.println("Input does not match criteria");
}

您可以从文件中读取数据并根据 1 个或多个 space 拆分字符串,并且可以处理由 space 分隔的多个输入。

        Scanner s = new Scanner(System.in);
        String line = s.nextLine();
        //String line = "98765432109876543210 9876543210987654321   ";
        String[] splited = line.split("\s+");

然后比较每个字符串,检查它是否是有效数字。 然后从该数字创建一个新的 BigDecimal。在内存允许的情况下,64 位 jvm 上的 BigDecimal 最多可以容纳 646456993 位数字。

        for (int i=0;i<splited.length;i++) {

            if(splited[i].matches("[0-9]*")){

                BigDecimal num = new BigDecimal(splited[i]);
                System.out.println("num "+(i+1)+"="+num);
            }
        }



 Results
 line ="98765432109876543210 9876543210987654321   "
 num 1=98765432109876543210
 num 2=9876543210987654321

 line ="1212312312312312312312313 123432432432432423432423432"
 num 1=1212312312312312312312313
 num 2=123432432432432423432423432