【问题标题】:Weird behaviour with Scanner#nextFloatScanner#nextFloat 的奇怪行为
【发布时间】:2011-06-10 03:25:25
【问题描述】:

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

price = sc.nextFloat();

在代码前添加这一行会使 Scanner 接受 0,23(法语表示法)作为浮点数:

Locale.setDefault(Locale.US);

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

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

编辑:这演示了 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);
    }

}

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

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

}

【问题讨论】:

  • 您能否给出一个可执行示例,显示您正在运行的代码的实际序列并显示问题?
  • 当然。我会在几分钟内添加一些代码。

标签: java java.util.scanner


【解决方案1】:

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

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

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

【讨论】:

  • 如果您不调用 useLocale(...) ,扫描器将使用默认语言环境构建。 OP 的默认语言环境是法语。
  • 感谢您的回复,但很抱歉我错过了。他在哪里声明默认语言环境是法语?
  • 谢谢。设置扫描仪的区域设置可以解决问题(我想使用美国十进制)。关于导致 nextLine 在修改后的代码中被跳过的任何想法?此外,由于设置了区域设置,我无法重现扫描仪似乎正在接受文本但无法识别回车的问题。
  • @hovercraft 在关于他的 println(Locale.getDefault()) 的评论中
  • @james 当您调用 sc.nextFloat() 时,它不会从缓冲区中删除换行符,因此您对 sc.nextLine() 的下一次调用将返回一个空行(正如@hovercraft 所解释的 - + 1!)解决方案是在 sc.nextFloat() 之后立即调用 sc.nextLine() 并忽略其输出
猜你喜欢
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 2015-07-20
  • 2010-10-03
  • 2021-07-12
  • 2013-10-04
相关资源
最近更新 更多