Domanda

Voglio leggere i dati sui caratteri MMORPG da un file .txt e quindi filtrare in base all'esperienza (esperienza minima). Ma sto ricevendo questa eccezione, di cui conosco il significato ma non capisco davvero cosa sto facendo di sbagliato.

Non sono bravo a Java, in realtà sono un principiante. Qualcuno può spiegarmelo? Probabilmente sto facendo qualcosa di molto stupido.

Questo è il mio codice:

Karakter (Personaggio):

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

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

 }

 }

E questo è l'errore:

 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)

queste righe:

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

questo è il file 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 
È stato utile?

Soluzione

Il problema è che su questa linea:

int experience = sc.nextInt();

Stai provando a leggere un " int " ma ciò che lo scanner legge è una stringa "experience"

Da questa riga nel tuo file .txt:

experience = 15

Quindi devi leggere due stringhe (1 st è " esperienza " e 2 nd è " = ") e poi sarai in grado di leggere un int (15) e così via.

Il primo non è fallito, perché a name è stata assegnata una stringa, ma se registri ciò che leggi, hai: " name " invece del vero nome.

Un'alternativa è lasciare che la classe ResourceBundle faccia la lettura per te. O anche la classe Properties .

Con ResourceBundle faresti qualcosa del tipo:

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

E dovresti nominarlo come: Karakters.properties

Modifica

Ho aggiunto un esempio di come farei usando ResouceBundle

Altri suggerimenti

InputMismatchException viene lanciato da uno scanner per indicare che il token recuperato non corrisponde al modello per il tipo previsto o che il token è fuori portata per il tipo previsto .

Quindi, suppongo che tu stia chiamando nextInt quando il token successivo non è in realtà un intero .

Modifica

Devi stare attento quando leggi quel file, perché hai etichette che contano come token. Ad esempio, quando hai:

maxHealthPoints = 20 ,

Hai tre token: " maxHealthPoints " ;, " = " ;, e " 20 " ;. Il problema è che stai ignorando sia l'etichetta (prima di " = ") sia il segno di uguale. Il mio consiglio? Leggi il tuo file riga per riga e usa Scanner per analizzare ogni riga. In alternativa, rimuovere le etichette e il segno di uguale dal file, lasciando solo i valori che si desidera estrarre.

La chiamata di next () ha risolto due volte il problema. Successivamente ho ricevuto un NullPointerException nel mio karaktersVanaf (minExp) in Karakters. Per risolvere questo problema ho aggiunto queste righe al mio codice:

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;
}

Ma ora vedo di nuovo InputMissMatschException ! Non so cosa sto sbagliando! Potrei fare qualcosa di totalmente sbagliato, quindi sii pronto a ridere.

A proposito, non ho ancora 15 punti esperienza, ecco perché non posso votare per te proprio ora. Lo farò appena posso.

Ogni volta che il tuo lettore fa un nextInt () o nextString (), non legge la riga successiva, legge i caratteri successivi separati da spazi bianchi (spazio o newline). Il modo più semplice per risolvere il tuo problema sarebbe rimuovere " name = " ;, " experience = " ;, e mettere semplicemente i dati univoci su ciascuna riga.

Quindi il tuo file sarebbe simile a:

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

E quindi il tuo codice funzionerà così com'è.

Ho codificato un modo per leggere usando ResourceBundle.

Lascio qui, spero che lo trovi 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

Output:

java Ktr
[Dursley{maxHealthPoints=20, maxGreed=3}, Aragorn{maxHealthPoints=40, maxGreed=20}]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top