使用 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
我使用 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