java - Scanner#nextFloat 的奇怪行为

标签 java java.util.scanner

最初在 Eclipse 中运行以下命令导致 Scanner 无法识别控制台中的回车符,有效地阻止了进一步的输入:

price = sc.nextFloat();

在代码之前添加这一行会导致 Scanner 接受 0,23(法语表示法)作为 float :

Locale.setDefault(Locale.US);

这很可能是由于 Windows XP Pro(法语/比利时语)中的区域设置所致。当代码再次运行时,0,23 仍然被接受,输入 0.23 会导致它抛出 java.util.InputMismatchException

关于为什么会发生这种情况的任何解释?还有解决方法还是我应该只使用 Float#parseFloat

编辑:这演示了扫描仪在不同区域设置下的行为方式(取消注释开头的一行)。

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);
    }

}

编辑:这重现了扫描器正在等待浮点值但在您按下回车键时无法触发的问题:

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);
    }

}

最佳答案

我想知道您是否没有正确处理行尾标记。通常,如果您使用 Scanner#next###()(nextLine 除外),并且当用户按下 enter 时到达行尾标记,如果您不处理行尾标记,它将阻止 Scanner反对适本地工作。要解决此问题,请在需要处理此 token 时调用 Scanner#nextLine()。如果您发布一些代码,我们可以看看这是否确实是您的问题,以及我的建议是否提供了解决方案。

编辑:不,您没有使用 System.in,所以这不是问题所在。另一方面,您确实需要在接受法国号码之前设置扫描器的区域设置。即,

     sc = new Scanner(frenchDecimal);
     sc.useLocale(Locale.FRENCH);
     price = sc.nextFloat();

关于java - Scanner#nextFloat 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4708219/

相关文章:

java - 输出格式打印带有两位小数和占位符的逗号

java - 在多行正则表达式模式之后解析文本行

java - 错误 :inputMismatchException?

java - 向后打印数组 - 不打印最后一个条目! - java

java - 从 .txt 文件读取后从 00 :00 format to a double 00. 00 格式转换字符串?

java - 使用扫描仪重复文件打印

使用类型转换的 Java 数组初始化

java - Gradle 3.0.0 的 Android 插件 : Could not find com. google.http-client :google-http-client-parent:1. 24.1

java - 使用 StompClient 在 Spring WebSocket 上传递消息时出错

java - 使用 Struts 2 调度程序结果时操作错误为空