5

I've been reading Java for the Dummies and I came across this error :

Exception in thread "main" java.util.InputMismatchException
    at java.util.Scanner.throwFor(Unknown Source)
    at java.util.Scanner.next(Unknown Source)
    at java.util.Scanner.nextDouble(Unknown Source)
    at TeamFrame.<init>(TeamFrame.java:18)
    at ShowTeamFrame.main(ShowTeamFrame.java:7)

This is the code :

import java.text.DecimalFormat;

public class Player {   
    private String name;
    private double average; 

    public Player(String name, double average) {
        this.name=name;
        this.average=average;
    }

    public String getName() {
        return name;
    }

    public double getAverage() {
        return average;
    }

    public String getAverageString() {
        DecimalFormat decFormat = new DecimalFormat();
        decFormat.setMaximumIntegerDigits(0);
        decFormat.setMaximumFractionDigits(3);
        decFormat.setMinimumFractionDigits(3);
        return decFormat.format(average);    
    }
}


import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.GridLayout;

@SuppressWarnings("serial")
public class TeamFrame extends JFrame {

    public TeamFrame() throws IOException {
         Player player;
        Scanner hankeesData = 
                    new Scanner(new File("d:/eclipse/Workplace/10-02 book/Hankees.txt"));

        for (int num = 1; num <= 9; num++) {
             player = new Player(hankeesData.nextLine(),
                    hankeesData.nextDouble());
            hankeesData.nextLine();

            addPlayerInfo(player);
        }        

        setTitle("The Hankees");
        setLayout(new GridLayout(9, 2, 20, 3));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setVisible(true);

        hankeesData.close();
    }

    void addPlayerInfo(Player player) {
        add(new JLabel("  " + player.getName()));
        add(new JLabel(player.getAverageString()));
    }   
}

import java.io.IOException;

class ShowTeamFrame {

    public static void main(String args[]) 
                               throws IOException {
        new TeamFrame();
    }
}

This is the .txt file:

Barry Burd
.101
Harriet Ritter
.200
Weelie J. Katz
.030
Harry "The Crazyman" Spoonswagler
.124
Filicia "Fishy" Katz
.075
Mia, Just "Mia"
.111
Jeremy Flooflong Jones
.102
I. M. D'Arthur
.001
Hugh R. DaReader
.212

It is taken right from the book's website so I think that there must be no error.

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
Stormlight
  • 53
  • 5
  • 1
    Please edit your post to fix the text file formatting, like it is here : http://188029.net/java/j11-11-22.html – Kevin Aug 24 '15 at 11:45
  • 1
    I think the double values are read as strings from the file.So you have to convert them to double first before storing them to objects – hermit Aug 24 '15 at 12:00
  • I've found my mistake. The problem was in the .txt file. I shoud have used "," instead of ".". – Stormlight Aug 24 '15 at 12:06

3 Answers3

4

Insert this in your code after hankeesData is created:

hankeesData.useLocale(java.util.Locale.ENGLISH);

I noticed that your program works if the "." is replaced with ",", and the new code now tells Scanner to use the english method.

Update: If you get a NoSuchElementException: No line found at the last input line, then this is because your last line doesn't have a \n. Use hasNextLine() as shown near the end of the answer of HyperZ.

Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
  • 1
    This is the correct answer. If the dots are what is used in the file provided by the book, then that's what a solution should parse. – ankh-morpork Aug 24 '15 at 12:11
  • 1
    @dohaqatar7 However this solution doesn't talk about a second problem, caused by the last `nextLine()` in the for loop. – Kevin Aug 24 '15 at 12:23
  • @HyperZ I didn't get any second problem after the fix. The green checkmark has been pressed, so my job here is done :-) – Tilman Hausherr Aug 24 '15 at 12:27
  • @TilmanHausherr If you left a blank line at the end of the file you won't get an error, but if there is no white line (which is probably the case), you will get a second exception, I tested it. – Kevin Aug 24 '15 at 12:29
  • @HyperZ ok, this is true, but that wasn't the question. All there is to do is to add if (!hankeesData.hasNext()) break; and move addPlayerInfo(player) before the "if". – Tilman Hausherr Aug 24 '15 at 12:33
  • 2
    @HyperZ That is why the POSIX standard states, that each file needs to end with an empty line: http://stackoverflow.com/questions/729692/why-should-files-end-with-a-newline :). – Tom Aug 24 '15 at 12:34
  • @TilmanHausherr I agree with you, however that second problem showed up when I answered the original problem, hence I found it necessary to answer it too. – Kevin Aug 24 '15 at 12:34
  • @Tom +1, didn't knew that! – Kevin Aug 24 '15 at 12:35
  • @HyperZ But we should mention, that most Windows application don't do that, so it is possible, that OP gets a problem due to the missing empty line. So it is good, that you've mentioned that :). – Tom Aug 24 '15 at 12:36
  • @HyperZ I've now added it and referred to your answer. – Tilman Hausherr Aug 24 '15 at 12:41
1

The text file should be formatted like this :

Barry Burd
,101
Harriet Ritter
,200
Weelie J. Katz
,030
Harry "The Crazyman" Spoonswagler
,124
Filicia "Fishy" Katz
,075
Mia, Just "Mia"
,111
Jeremy Flooflong Jones
,102
I. M. D'Arthur
,001
Hugh R. DaReader
,212

So the problem was that the value of type double was provided like this x.xxx instead of x,xxx , which was causing the exception!

This solves the current exception, however with the code unchanged you will get another error : Exception in thread "main" java.util.NoSuchElementException: No line found

Let us look at the for loop :

for (int num = 1; num <= 9; num++) {
    player = new Player(hankeesData.nextLine(),
                hankeesData.nextDouble());
    hankeesData.nextLine(); // Go to next line, this is causing the problem
    addPlayerInfo(player);
}

When iterating the last time (i.e. num = 9) we read the player's name, then we read it's average. But then we do hankeesData.nextLine(); again! However, the average value was the last line in this text file and there is nothing more to read, hence doing hankeesData.nextLine(); a last time will result in the No line found exception.

for (int num = 1; num <= 9; num++) {
    player = new Player(hankeesData.nextLine(),
                    hankeesData.nextDouble());

    if (hankeesData.hasNextLine())
       hankeesData.nextLine(); // Go to next line, only if there is a next line!

    addPlayerInfo(player);
}
Kevin
  • 2,813
  • 3
  • 20
  • 30
  • 1
    @Stormlight no problem! I will edit this post because the second `nextLine()` in your for loop is causing problems for the last player. – Kevin Aug 24 '15 at 12:07
-2

The Exception you're is an InputMismatchExceptionthrown by the Scanner.nextDouble() method. In the Javadocs for Scanner, it is stated that InputMismatchException is thrown

if the next token does not match the Float regular expression, or is out of range

In the same docs we can find the Float regular expression.

Float:
    Decimal | HexFloat | SignedNonNumber

Decimal:
    ( [-+]? DecimalNumeral Exponent? )
    | LocalPositivePrefix DecimalNumeral LocalPositiveSuffix Exponent?
    | LocalNegativePrefix DecimalNumeral LocalNegativeSuffix Exponent?

HexFloat:
    [-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+ ([pP][-+]?[0-9]+)?

NonNumber:
   NaN | LocalNan | Infinity | LocalInfinity

SignedNonNumber:
    ( [-+]? NonNumber )
    | LocalPositivePrefix NonNumber LocalPositiveSuffix
    | LocalNegativePrefix NonNumber LocalNegativeSuffix

For your case the only important part is under decimal, the regex for a base 10 double number.


To fix your code, try adding this:

 if(!hankeesData.hasNextLine()){
     break;
 }

before:

 hankeesData.nextLine();
ankh-morpork
  • 1,732
  • 1
  • 19
  • 28