java Scanner#nextFloat 的奇怪行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4708219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Weird behaviour with Scanner#nextFloat
提问by James P.
Running the following in Eclipse initially caused Scanner to not recognize carriage returns in the console effectively blocking further input:
在 Eclipse 中运行以下最初导致 Scanner 无法识别控制台中的回车,从而有效地阻止了进一步的输入:
price = sc.nextFloat();
Adding this line before the code causes Scanner to accept 0,23 (french notation) as a float:
在代码之前添加这一行会导致 Scanner 接受 0,23(法语符号)作为浮点数:
Locale.setDefault(Locale.US);
This is most probably due to regional settings in Windows XP Pro (French/Belgian). When the code is run again 0,23 is still accepted and entering 0.23 causes it to throw a java.util.InputMismatchException
.
这很可能是由于 Windows XP Pro(法语/比利时)中的区域设置所致。当代码再次运行时,0,23 仍然被接受,输入 0.23 会导致它抛出一个java.util.InputMismatchException
.
Any explanation as to why this is happening? Also is there a workaround or should I just use Float#parseFloat
?
关于为什么会发生这种情况的任何解释?也有解决方法还是我应该使用Float#parseFloat
?
Edit: This demonstrates how Scanner behaves with different Locales (uncomment one of the lines at the beginning).
编辑:这演示了 Scanner 在不同语言环境下的行为(取消注释开头的一行)。
import java.util.Locale;
import java.util.Scanner;
public class NexFloatTest {
public static void main(String[] args) {
//Locale.setDefault(Locale.US);
//Locale.setDefault(Locale.FRANCE);
// Gives fr_BE on this system
System.out.println(Locale.getDefault());
float price;
String uSDecimal = "0.23";
String frenchDecimal = "0,23";
Scanner sc = new Scanner(uSDecimal);
try{
price = sc.nextFloat();
System.out.println(price);
} catch (java.util.InputMismatchException e){
e.printStackTrace();
}
try{
sc = new Scanner(frenchDecimal);
price = sc.nextFloat();
System.out.println(price);
} catch (java.util.InputMismatchException e){
e.printStackTrace();
}
System.out.println("Switching Scanner to System.in");
try{
sc = new Scanner(System.in);
System.out.println("Enter a float value");
price = sc.nextFloat();
System.out.println(price);
} catch (java.util.InputMismatchException e){
e.printStackTrace();
}
System.out.print("Enter title:");
String title = sc.nextLine(); // This line is skipped
System.out.print(title);
}
}
Edit: This reproduces the issue where the Scanner is waiting for a float value but fails to trigger when you press return:
编辑:这重现了扫描器正在等待浮点值但在您按下回车时无法触发的问题:
import java.util.Scanner;
public class IgnoreCRTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a float value:");
// On french Locale use , as the decimal separator
float testFloat = sc.nextFloat();
System.out.println(testFloat);
//sc.skip("\n"); // This doesn't solve the issue
sc.nextLine();
System.out.println("Enter an integer value:");
int testInt = sc.nextInt();
System.out.println(testInt);
// Will either block or skip here
System.out.println("Enter a string value :");
String testString = sc.nextLine();
System.out.println(testString);
}
}
采纳答案by Hovercraft Full Of Eels
I wonder if you're not handling an end of line token appropriately. Often if you use Scanner#next###() (except for nextLine), and you reach an end of line token as when the user presses enter, if you don't handle the end of line token, it will prevent the Scanner object from working appropriately. To solve this, call Scanner#nextLine() when this token needs to be handled. If you post some of your code, we can see if this indeed is your problem and if my suggestion offers a solution.
我想知道您是否没有适当地处理行尾令牌。通常,如果您使用 Scanner#next###()(nextLine 除外),并且当用户按 Enter 时到达行尾标记,如果您不处理行尾标记,则会阻止 Scanner对象不能正常工作。要解决此问题,请在需要处理此令牌时调用 Scanner#nextLine()。如果您发布一些代码,我们可以看看这是否确实是您的问题,以及我的建议是否提供了解决方案。
edit: nope, you're not using System.in so this is not the problem. On the other hand, you do need to set the locale of the Scanner before accepting the French number. i.e.,
编辑:不,你没有使用 System.in 所以这不是问题。另一方面,在接受法语号码之前,您确实需要设置扫描仪的区域设置。IE,
sc = new Scanner(frenchDecimal);
sc.useLocale(Locale.FRENCH);
price = sc.nextFloat();