Pregunta

Quiero leer datos sobre caracteres MMORPG de un archivo .txt y luego filtrar por experiencia (experiencia mínima). Pero recibo esta excepción, de la que sé el significado, pero realmente no entiendo lo que estoy haciendo mal.

No soy bueno en Java, en realidad soy un principiante. ¿Alguien puede explicarme esto? Probablemente estoy haciendo algo muy estúpido.

Este es mi código:

Karakter (personaje):

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

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étodo principal):

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

 }

 }

Y este es el 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)

estas líneas:

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

este es el archivo 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 
¿Fue útil?

Solución

El problema es que en esta línea:

int experience = sc.nextInt();

Está intentando leer un " int " pero lo que lee el escáner es una cadena "experience"

Desde esta línea en su archivo .txt:

experience = 15

Por lo tanto, debe leer dos cadenas (1 st es " experience " y 2 ?? nd es " = ") y luego podrá leer un int (15) y así sucesivamente.

El primero no falló porque a name se le asignó una Cadena, pero si registra lo que leyó, obtendrá: " name " en lugar del nombre real

Una alternativa es dejar que la clase ResourceBundle haga la lectura por usted. O incluso la clase Properties .

Con ResourceBundle harías algo como:

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

Y tendría que nombrar eso como: Karakters.properties

EDIT

He agregado una muestra de cómo lo haría usando ResouceBundle

Otros consejos

InputMismatchException es arrojado por un escáner para indicar que el token recuperado no coincide con el patrón para el tipo esperado, o que el token está fuera del rango para el tipo esperado .

Entonces, supongo que está llamando a nextInt cuando el siguiente token no es realmente un Integer .

EDIT

Debe tener cuidado al leer ese archivo, porque tiene etiquetas que cuentan como tokens. Por ejemplo, cuando tienes:

maxHealthPoints = 20 ,

Tiene tres tokens: " maxHealthPoints " ;, " = " ;, y " 20 " ;. El problema es que está ignorando tanto la etiqueta (antes de " = ") como el signo igual. ¿Mi consejo? Lea su archivo línea por línea y use el Escáner para analizar cada línea. Alternativamente, elimine las etiquetas y el signo igual del archivo, dejando solo los valores que desea extraer.

Llamar a next () dos veces solucionó el problema. Después de eso obtuve una NullPointerException en mi karaktersVanaf (minExp) en Karakters. Para solucionar esto, agregué estas líneas a mi código:

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

¡Pero ahora estoy viendo la InputMissMatschException nuevamente! ¡No sé lo que estoy haciendo mal! Puede que esté haciendo algo totalmente incorrecto, así que prepárate para reír.

Por cierto, todavía no tengo 15 puntos de experiencia, es por eso que no puedo votar por ti en este momento. Lo haré tan pronto como pueda.

Cada vez que su lector hace un nextInt () o nextString (), no lee la siguiente línea, lee los siguientes caracteres separados por espacios en blanco (espacio o nueva línea). La forma más sencilla de solucionar su problema sería eliminar el " name = " ;, " experience = " ;, y simplemente colocar los datos únicos en cada línea.

Entonces su archivo se vería así:

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

Y luego su código funcionará como está.

He codificado una forma de leer usando ResourceBundle.

Lo dejo aquí, espero que les sea útil:

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

Salida:

java Ktr
[Dursley{maxHealthPoints=20, maxGreed=3}, Aragorn{maxHealthPoints=40, maxGreed=20}]
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top