Question

Je souhaite lire des données sur les caractères MMORPG à partir d'un fichier .txt, puis filtrer en fonction de l'expérience (expérience minimale). Mais je reçois cette exception, dont je connais le sens, mais je ne comprends vraiment pas ce que je fais mal.

Je ne suis pas bon en Java, je suis débutant en fait. Quelqu'un pourrait-il me l'expliquer? Je fais probablement quelque chose de très stupide.

Ceci est mon code:

Karakter (Personnage):

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 (personnages):

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 (méthode principale):

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());

 }

 }

Et voici l'erreur:

 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)

ces lignes:

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

il s'agit du fichier txt:

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 
Était-ce utile?

La solution

Le problème est que sur cette ligne:

int experience = sc.nextInt();

Vous essayez de lire un " int " mais ce que le scanner lit est une chaîne " expérience "

À partir de cette ligne dans votre fichier .txt:

experience = 15

Il faut donc lire deux chaînes (1 e est "expérience" et 2 nd est "" = "") et vous pourrez alors lire un int (15) et ainsi de suite.

La première n'a pas échoué, car name a été attribué à une chaîne, mais si vous enregistrez ce que vous avez lu, vous obtenez: "name". au lieu du vrai nom.

Une alternative consiste à laisser la classe ResourceBundle effectuer la lecture à votre place. Ou même la classe Properties .

Avec ResourceBundle, vous feriez quelque chose comme:

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

Et vous devrez le nommer comme suit: Karakters.properties

MODIFIER

J'ai ajouté un exemple sur la façon dont je procéderais avec ResouceBundle

.

Autres conseils

InputMismatchException est envoyé par un scanner pour indiquer que le jeton récupéré ne correspond pas au modèle pour le type attendu ou que le jeton est en dehors des limites du type attendu .

Donc, je suppose que vous appelez nextInt lorsque le prochain jeton n'est pas réellement un entier .

MODIFIER

Vous devez faire attention lorsque vous lisez ce fichier, car vous avez des étiquettes qui comptent comme des jetons. Par exemple, lorsque vous avez:

maxHealthPoints = 20 ,

Vous avez trois jetons: "maxHealthPoints", "=", "et 20". Le problème est que vous ignorez à la fois l'étiquette (avant "=") et le signe égal. Mon conseil? Lisez votre fichier ligne par ligne et utilisez Scanner pour analyser chaque ligne. Vous pouvez également supprimer les étiquettes et le signe égal du fichier, en ne laissant que les valeurs que vous souhaitez extraire.

L'appel de next () à deux reprises a résolu le problème. Après cela, j'ai reçu une NullPointerException dans mon karaktersVanaf (minExp) dans Karakters. Pour résoudre ce problème, j'ai ajouté ces lignes à mon 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;
}

Mais maintenant, je vois à nouveau InputMissMatschException ! Je ne sais pas ce que je fais mal! Je fais peut-être quelque chose de totalement faux alors soyez prêt à rire.

En passant, je n'ai pas encore 15 points d'expérience, c'est pourquoi je ne peux pas voter pour vous pour l'instant. Je le ferai dès que je pourrai le faire.

Chaque fois que votre lecteur effectue une action nextInt () ou nextString (), il ne lit pas la ligne suivante, il lit les caractères suivants séparés par des espaces (espaces ou nouvelles lignes). Le moyen le plus simple de résoudre votre problème serait de supprimer le "name =", "experience" et de simplement mettre les données uniques sur chaque ligne.

Votre fichier ressemblera donc à:

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

Ensuite, votre code fonctionnera tel quel.

J'ai codé un moyen de lire à l'aide de ResourceBundle.

Je le laisse ici, j'espère que vous le trouverez utile:

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

Sortie:

java Ktr
[Dursley{maxHealthPoints=20, maxGreed=3}, Aragorn{maxHealthPoints=40, maxGreed=20}]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top