1

hello i have a problem when following a tutorial in youtube (the code is in java, i am using intelliji idea)

import java.text.NumberFormat;
import java.util.Locale;
import java.util.Scanner;

public class Main {
    public static void main(String[] arg) {
        final byte MONTHS_IN_YEAR = 12;
        final byte PERCENT = 100;
        Scanner scanner = new Scanner(System.in);

        System.out.print("Principal: ");
        int principal = scanner.nextInt();

        System.out.print("Annual Interest Rate: ");
        float annualInterest = scanner.nextFloat();
        float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

        System.out.print("Period (Years): ");
        byte years = scanner.nextByte();
        int numberOfPayments = years * MONTHS_IN_YEAR;

        double mortgage = principal
                * (monthlyInterest * Math.pow(1 + monthlyInterest, numberOfPayments))
                / (Math.pow(1 + monthlyInterest, numberOfPayments) - 1);
        String mortgageFormatted = NumberFormat.getCurrencyInstance(Locale.US).format(mortgage);
        System.out.println("Mortgage: " + mortgageFormatted);
    }
}

The problem is when i input the Annual Interest Rate (like 3.92) it give me the following error:

Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:947)
    at java.base/java.util.Scanner.next(Scanner.java:1602)
    at java.base/java.util.Scanner.nextFloat(Scanner.java:2505)
    at com.codewithtamer.Main.main(Main.java:17)

And thank you for helping a beginner like me :), + i think i somehow messed up the format of this post sorry

3 Answers3

2

If you want to use a Locale with your Scanner which is different to your default locale (the one Java gets from the operating system) you can do this:

class App {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println(s.locale());
        s.useLocale(Locale.US);
        System.out.println(s.nextFloat());
    }
}

That will show your current locale (for me it prints en_AU) and then sets the scanner to use a different locale.

Locale.US with require . as a decimal separator, Locale.FRANCE requires , and so on.

tgdavies
  • 10,307
  • 4
  • 35
  • 40
0

Unfortunately in some versions of some IDEs the java.util.Scanner reads decimals in European mode (i.e. with a decimal comma). This has been observed in Eclipse and Netbeans as suggested by this StackOverflow Q&A (Scanner.next... throws java.util.InputMismatchException for Float but not for Int). You could look into changing the version of your IDE, or you could write the percent with a comma (not ideal), or you can instead rely on Float.parseFloat() such as in the following:

System.out.print("Annual Interest Rate: ");
float annualInterest = Float.parseFloat(scanner.next());
float monthlyInterest = annualInterest / PERCENT / MONTHS_IN_YEAR;

This should work with a decimal point as Float.parseFloat() is not location-dependent and always expects a decimal point.

MorganS42
  • 656
  • 4
  • 21
  • i am sorry but the comma "," don't work also: float annualInterest = Float.parseFloat(scanner.next()); with a dot "." don't work – Tamer Karar Jul 02 '23 at 20:53
  • That is strange, sorry that it didn't work, I'm looking into the issue further. It seems like a bug report or two has been filed regarding the functionality of scanner.nextFloat() in some versions of Java (https://bugzilla.redhat.com/show_bug.cgi?id=452235) but that is also regarding the decimal comma. Worst case scenario you could try reinstalling a new version of Java, but I'll try to find another solution first. – MorganS42 Jul 02 '23 at 21:03
  • Is it possible that the issue is related to my pc language? Since it is arabic – Tamer Karar Jul 02 '23 at 21:04
  • It could be! Try using an Arabic decimal separator (٫) it looks like a comma but is slightly different it is the Unicode character U+066B. Let me know if that works – MorganS42 Jul 02 '23 at 21:05
  • Also try that with the original code (i.e. scanner.nextFloat()) – MorganS42 Jul 02 '23 at 21:06
  • haha the arabic decimal separator worked with original code scanner.nextFloat, now how to make the dot work since i don't want the arabic one every time i use float – Tamer Karar Jul 02 '23 at 21:16
  • That's good! The Float.parseFloat() should work with the decimal point (.) as it is not language dependent, if not that is strange, could you try the Float.parseFloat() with the Arabic decimal separator as a test? – MorganS42 Jul 02 '23 at 21:19
  • hmm i guess i messed up with Float.parseFloat last time idk how, now be it arabic or english dot it work just fine – Tamer Karar Jul 02 '23 at 21:24
  • Great! If that works do you mind setting this answer as correct? – MorganS42 Jul 02 '23 at 21:25
  • done, btw if i want to make the dot work with scanner.nextFloat i need to change the IDE version right? i have the last version btw – Tamer Karar Jul 02 '23 at 21:27
  • I’m not entirely sure, some sources suggest that it’s the IDE others suggest it’s the version of Java. It may be detecting your computer’s language, but as I said I’m not sure. It may be worth posting another question with the language information. – MorganS42 Jul 02 '23 at 21:41
  • Turns out you only need to add this line of code: scanner.useLocale(Locale.ENGLISH) and bam java ignore your operation system language – Tamer Karar Jul 02 '23 at 22:31
-1

As per the JavaDoc for Scanner#nextFloat,

"... Throws [an] InputMismatchException if the next token does not match the Float regular expression, or is out of range ...".

And, the same goes for the nextInt method—the exception is thrown if the value is not an integer value.

Although, as a note, you can use the nextFloat to capture integer values.

For example,

Principal: 1
Annual Interest Rate: 2
Period (Years): 3
Mortgage: $0.03

And,

Principal: 1.23
Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:947)
    at java.base/java.util.Scanner.next(Scanner.java:1602)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2267)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2221)
    at Example.main(Example.java:14)
Reilas
  • 3,297
  • 2
  • 4
  • 17