33

I tried use scanner at easiest way:

Code:

double gas, efficiency, distance, cost;
Scanner scanner = new Scanner(System.in);

System.out.print("Enter the number of gallons of gas in the tank: ");
gas = scanner.nextDouble();
System.out.print("Enter the fuel efficiency: ");
efficiency = scanner.nextDouble();

But after first input 5.1 it throws:

Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor(Scanner.java:909)
    at java.util.Scanner.next(Scanner.java:1530)
    at java.util.Scanner.nextDouble(Scanner.java:2456)
    at udacity.MileagePrinter.main(MileagePrinter.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

The JavaDocs state:

Thrown by a Scanner to indicate that the token retrieved does not match the
pattern for the expected type, or that the token is out of range for the expected type.

But to my mind all look correctly, and should work OK.

Questions:

  • Why this happen at this situation?
  • How to circumvent this trouble?
Roman C
  • 49,761
  • 33
  • 66
  • 176
catch23
  • 17,519
  • 42
  • 144
  • 217

2 Answers2

46

You should precise a Locale for your Scanner.

Scanner scanner = new Scanner(System.in).useLocale(Locale.US);

From the doc :

An instance of this class is capable of scanning numbers in the standard formats as well as in the formats of the scanner's locale. A scanner's initial locale is the value returned by the Locale.getDefault() method; it may be changed via the useLocale(java.util.Locale) method

The localized formats are defined in terms of the following parameters, which for a particular locale are taken from that locale's DecimalFormat object, df, and its and DecimalFormatSymbols object, dfs.

So your default locale use certainly a DecimalFormat that expect a comma as a decimal delimiter instead of a dot.

Community
  • 1
  • 1
Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • 3
    `.useLocale()` returns `this`, you can shorten that to `new Scanner(System.in).useLocale(Locale.US)` – fge Jun 17 '13 at 15:02
  • I tried running this program but couldn't face any problem. May I know why is that? – Prasad Kharkar Jun 17 '13 at 15:05
  • 2
    @PrasadKharkar probably because in your JVM's default locale, the decimal number separator is the dot – fge Jun 17 '13 at 15:06
  • 1
    @nazar_art import the correct package; `Locale` is in `java.util.Locale` – fge Jun 17 '13 at 15:07
  • @nazar_art you are using Intellij IDEA? Imports should be automatic... At worst it asks you what to import. – fge Jun 17 '13 at 15:15
  • @ZouZou Yes Intellij IDEA. And it gives import only after `Alt` + `Enter` – catch23 Jun 17 '13 at 15:18
  • And after that import Locale `import java.util.Locale;` (I'm beginner so it took few seconds to understand whats wrong in my code :P ) – P_95 Mar 24 '17 at 12:08
  • Instead of Locale.US, use Locale.ROOT. This is documented as "the language/country neutral locale for the locale sensitive operations". A user in Europe or Asia shouldn't have to use the locale of some random foreign country like the US. – k314159 Feb 20 '23 at 12:55
6

Make sure that you are using the correct locale

Scanner scanner = new Scanner(System.in).useLocale(Locale.US);

Maybe you are using a locale where "," is the decimal delimiter

Viktor Mellgren
  • 4,318
  • 3
  • 42
  • 75