views:

103

answers:

6

I want to read data about MMORPG characters from a .txt file and then filter on experience (minimum experience). But I'm getting this exception, which I know the meaning of but I really don't understand what I'm doing wrong. this my code:

I'm not good at java, I'm a beginner actually. Can someone please explain this to me. Probably I'm soing something very stupid :P

Karakter (Character):

import java.util.Scanner;


public class Karakter {

 private String name;
 private int experience;
 private int maxHealthPoints;
 private int healthPoints;
 private int maxGreed;
 private int greed;

 public Karakter(String nm, int exp, int mHP, int hp, int mG, int g)
 {
  name = nm;
  experience = exp;
  maxHealthPoints = mHP;
  healthPoints = hp;
  maxGreed = mG;
  greed = g;
 }

 public String toString()
 {
  String s = "";
  s += getName(); 
  s += getExperience();
  s += getMaxHealthPoints();
  s += getHealthPoints();
  s += getMaxGreed(); 
  s += getGreed();
  return s;
 }

 public static Karakter read(Scanner sc)
 {
  String name = sc.next();
  int experience = sc.nextInt();
  int maxHealthPoints = sc.nextInt();
  int healthPoints = sc.nextInt();
  int maxGreed = sc.nextInt();
  int greed = sc.nextInt();
  return new Karakter(name, experience, maxHealthPoints, healthPoints, maxGreed, greed);
 }

 public boolean hasExperience(int min)
 {
  return experience >= min;
 }
 // returns true if Krakters have the same name
 public boolean equals(Object other)
 {
  if(!(other instanceof Karakter))
  {
   return false;
  }
  else
  {
   Karakter that = (Karakter) other;
   return that.name == this.name;
  }
 }

 public String getName()
 {
  return name;
 }

 public int getExperience()
 {
  return experience;
 }

 public int getMaxHealthPoints()
 {
  return maxHealthPoints;
 }

 public int getHealthPoints()
 {
  return healthPoints;
 }

 public int getMaxGreed()
 {
  return maxGreed;
 }

 public int getGreed()
 {
  return greed;
 }


}

Karakters (Characters):

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class Karakters {



private ArrayList<Karakter> kars = new ArrayList<Karakter>();

 public void voegToe(Karakter kar)
 {
  if(!kars.contains(kar))
  {
   kars.add(kar);
  }
 }

 // returns an arraylist of characters with exp >= minexp

 public ArrayList<Karakter> karaktersVanaf(int minExperience)
 {
  Karakter kar = null;
  for(int i = 0; i < kars.size(); i++)
  {
   if(kar.hasExperience(minExperience))
    kars.add(kar);
  }
  return kars;
 }

 public static Karakters read(String infile)
 {
  Karakters k = new Karakters();
  try
  {
   FileReader fr = new FileReader(infile);
   Scanner sc = new Scanner(fr);
   int aantal = sc.nextInt();
   for(int i = 0; i < aantal ; i++)
   {
    Karakter kar = Karakter.read(sc);
    k.kars.add(kar);
   }
   fr.close();
  }
  catch(IOException iox)
  {
   System.out.println(iox);
   return null;
  }
  return k;
 }

}

KarakterZoeker (Main method):

import java.util.ArrayList;
import java.util.Scanner;


public class KarakterZoeker {


 public static void main(String[] args)
 {


  Scanner sc = new Scanner(System.in);
  Karakters kars = Karakters.read("infile.txt");

  System.out.println("Welke experience wilt u minimaal?");
  int minExp = sc.nextInt();

  ArrayList<Karakter> s = kars.karaktersVanaf(minExp);

  System.out.println(s.toString());

 }

 }

And this is the 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.nextInt(Unknown Source)
 at java.util.Scanner.nextInt(Unknown Source)
 at Karakter.read(Karakter.java:38)
 at Karakters.read(Karakters.java:41)
 at KarakterZoeker.main(KarakterZoeker.java:14)

these lines:

Karakter kar = Karakter.read(sc);  (in Karakters)
int experience = sc.nextInt();   (in Karakter)
Karakters kars = Karakters.read("infile.txt");  (in KarakterZoeker)

this is the txt file:

2
name = Dursley
experience = 15
maxHealthPoints = 20
healthPoints = 10
maxGreed = 3
greed = 1
name = Aragorn
experience = 45
maxHealthPoints = 40
healthPoints = 30
maxGreed = 20
greed = 10
+1  A: 

InputMismatchException is 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.

So, my guess is that you are calling nextInt when the next token isn't actually an Integer.

EDIT

You need to be careful when reading that file, because you have labels that count as tokens. For instance, when you have:

maxHealthPoints = 20 ,

You have three tokens: "maxHealthPoints", "=", and "20". The problem is that you are ignoring both the label (before "=") and the equal sign. My advice? Read your file line by line and use the Scanner to parse each line. Alternatively, remove the labels and the equal sign from the file, leaving just the values you want to extract.

JG
Sorry you're right, I added the input file :)
Nima
So I have to use nextLine()? and then how can I only take the Integer? sorry I'm a noob :P
Nima
You have to take the first two tokens (label and equal sign), and only then you can retrieve the value that you want. For instance, to retrieve `20` in `maxHealthPoints = 20`, you'd have to call: `next()`, `next()`, and finally `nextInt()`.
JG
A: 

Each time your reader does a nextInt() or nextString(), it doesn't read the next line, it reads the next characters separated by whitespace (space or newline). The simplest way to fix your problem would be to remove the "name =", "experience =", and just put the unique data on each line.

So your file would look like:

2
Dursley
15
20
10
3
1
Aragorn
45
40
30
20
10

And then your code will work as is.

Kaleb Brasee
A: 

I have coded a way to read using ResourceBundle.

I leave it here, I hope you find it useful:

import java.util.*;

public class Ktr {
       public static void main( String [] args ) {

           ResourceBundle b = ResourceBundle.getBundle("k");
           String names = b.getString("names");

           List<K> l = new ArrayList<K>();
           for( String name : names.split(",")){
               l.add( K.read( name, b ));
           }

           System.out.println( l );
       }
}

class K {

    private String name;
    private int maxHealthPoints;
    private int maxGreed;
    // etc.. 

    public static K read( String name, ResourceBundle b ) {
        K k = new K();
        k.name              = name;
        k.maxHealthPoints   = 
            Integer.parseInt(b.getString( name + ".maxHealthPoints") );

        k.maxGreed          = 
            Integer.parseInt(b.getString( name + ".maxGreed") );
        // you get the idea 
        return k;
    }
    public String toString() {
        return String.format("%s{maxHealthPoints=%d, maxGreed=%d}", 
                                name, maxHealthPoints, maxGreed);
    }
}

k.properties

names=Dursley,Aragorn
Dursley.maxHealthPoints=20
Dursley.maxGreed=3

Aragorn.maxHealthPoints=40
Aragorn.maxGreed=20

Output:

java Ktr
[Dursley{maxHealthPoints=20, maxGreed=3}, Aragorn{maxHealthPoints=40, maxGreed=20}]
OscarRyz
Thanks for the code, really informative :)
Nima
You're welcome.
OscarRyz
A: 

The problem is that on this line:

int experience = sc.nextInt();

You are trying to read a "int" but what the scanner reads is a string "experience"

From this line in your .txt file:

experience = 15

So you have to read two strings ( 1st is "experience" and 2nd is "=" ) and then you will be able to read an int ( 15 ) and so on.

The first one didn't failed, because name was assigned a String, but if you log what you read, you've got: "name" instead of the real name.

An alternative is to let the ResourceBundle class do the read for you. Or even the Properties class.

With ResourceBundle you would do something like:

ResourceBundle bundle = ResourceBundle.getBundle("Karakters");
String exp = bundle.getString("experience");
int experience = Integer.parseInt( exp );

And you would have to name that as: Karakters.properties

EDIT

I have added a sample on how I would do this using ResouceBundle

OscarRyz
A: 

Thank you all for your comments, I really appreciate it. I got rid of the InputMissMatchException but I'm getting nullpointerException:

Exception in thread "main" java.lang.NullPointerException
at Karakters.karaktersVanaf(Karakters.java:25)
at KarakterZoeker.main(KarakterZoeker.java:19)

these lines:

public ArrayList<Karakter> karaktersVanaf(int minExperience)
{
 Karakter kar = null;
 for(int i = 0; i < kars.size(); i++)
 {
  if(kar.hasExperience(minExperience))   //<---- here
   kars.add(kar);
 }
 return kars;
}

public static void main(String[] args)
{


 Scanner sc = new Scanner(System.in);
 Karakters kars = Karakters.read("infile.txt");

 System.out.println("Welke experience wilt u minimaal?");
 int minExp = sc.nextInt();

 ArrayList<Karakter> s = kars.karaktersVanaf(minExp); //<---- here

 System.out.println(s.toString());


}
Nima
Open a new quesion. The problem is you're first declaring: `Karakter kar = null;` and then: `kar.hasExperience...` which is `null.hasExperience` result in NullPointerException
OscarRyz
So i have to read the file before I test for hasExperience? Karakter kar = Karakter.read(?), read in Karakter needs a Scanner. I don't know how to do this?
Nima
Yeap, you have to make that var `Karakter kar` has "something" in it before you can use it.
OscarRyz
Sorry I can't upvote because I don't have 15 reputations yet :P Of course I would do that if I could :)
Nima
+1  A: 

calling next() twice fixed the problem. After that I got a NullPointerException in my karaktersVanaf(minExp) in Karakters. To fix this I added to lines to my code:

public ArrayList<Karakter> karaktersVanaf(int minExperience) throws           FileNotFoundException
{
 Scanner sc = new Scanner(new FileReader("infile.txt")); // --------line 1
 Karakter kar = Karakter.read(sc); // ------------ line 2
 for(int i = 0; i < kars.size(); i++)
 {
  if(kar.hasExperience(minExperience))
   kars.add(kar);
 }
 return kars;
}

But now I'm seeing the InputMissMatschException again! I don't know what I'm doing wrong! I maybe doing something totally wrong so be ready to laugh :P btw: I don't have 15 experience points yet, that's why I can't vote for you just now. I will do that as soon as I can do so.

Nima