3

I am unable to enter doubles value in my program from my bash terminal. Below is the code I used to figure out why it is happening.

This is my code for the test:

import java.util.*;
public class DoubleTest {
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);

        double n = sc.nextDouble();
        System.out.println(n);
    } 
}

With the following input 5, I get the expected results.

user $ java DoubleTest
   5
   5.0

Now to the interesting part. I input a Double as declared in the code, and this happens:

user $ java DoubleTest
5.0
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextDouble(Scanner.java:2564)
at DoubleTest.main(DoubleTest.java:6)

And when giving a value of 5,0 - this is the result:

user $ java DoubleTest
5,0
5.0

So it seems that the . (dot) is not working, but instead , (comma) is.

I already checked my locale, but that shouldn't be the problem.

LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
Shawn
  • 47,241
  • 3
  • 26
  • 60
  • Just to be sure: The usual format in Denmark is using a comma, right? – Marco13 Jan 30 '19 at 16:11
  • As RKrum pointed out: The `Scanner` will use the default locale. It's not clear where your information about your locale came from, but calling `Locale.setDefault(Locale.ENGLISH);` basically as "the first line of your `main` method" should be worth a try... – Marco13 Jan 30 '19 at 21:28

1 Answers1

2

Your Scanner is probably using the Denmark Locale as it uses , to format double variables instead of US default ..

Here is how you can check it (I tried locally forcing my Scanner to use Denmark Locale and it behaves the same way as in your experiments):

Scanner sc = new Scanner(System.in);
System.out.println(sc.locale().getDisplayCountry());

If this is your case, you need to set it to use the US Locale or any other you want:

Scanner sc = new Scanner(System.in);
sc.useLocale(Locale.US);
System.out.println(sc.locale().getDisplayCountry());

Alternatively, if you need to accept both , and . you could simply use a formatter. Here is one example with NumberFormat using France as Locale, which formats correctly both , and .:

NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE);
double doubleComma = numberFormat.parse("5,0").doubleValue();
double doubleDot = numberFormat.parse("5.0").doubleValue();

In your code you would do something like:

public static void main (String[] args) {
    try{
        Scanner sc = new Scanner(System.in);

        NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE);
        double n = numberFormat.parse(sc.next()).doubleValue();
        System.out.println(n);
    } catch (ParseException e) {
        e.printStackTrace();
    }
} 
RKrum
  • 410
  • 5
  • 15
  • 1
    Replacing *might* be a bit brittle. Depending on whether `.` or `,` is the standard separator, the number `1,234` might either mean `1.234` or `1234`. So before attempting to *fix* this issue, it might be worthwhile to figure out why it appears in the first place... – Marco13 Jan 30 '19 at 16:32
  • Makes sense. Thanks for the heads up! Changed my answer with some experiments – RKrum Jan 30 '19 at 17:33
  • Thank you for the help. Would there be a way for me to set the US locale as default for my JVM? So I wouldn't have to explicitly define it in every program – user10991282 Jan 30 '19 at 18:49
  • user10991282 The Locale is determined in some different ways depending on your system settings. You can do some reading about it here: https://www.oracle.com/technetwork/articles/javase/locale-140624.html#using – RKrum Jan 30 '19 at 19:57
  • Alternatively, setting it using JVM arguments when launching your app should work. Example: "java -Duser.country=US -Duser.language=en -jar yourJar.jar" – RKrum Jan 30 '19 at 20:02