Странное поведение сканера # nextFloat

Выполнение следующего в Eclipse первоначально заставило Scanner не распознавать возврат каретки в консоли, эффективно блокируя дальнейший ввод:

price = sc.nextFloat();

Добавление этой строки перед кодом заставляет Scanner принимать 0,23 (французский обозначение) в виде числа с плавающей запятой:

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

}

Изменить: Это воспроизводит проблему, при которой сканер ожидает значения с плавающей запятой, но не запускается при нажатии клавиши 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);
    }

}
13
задан skaffman 7 May 2011 в 15:50
поделиться