En ocasiones podemos tener problemas con el formato de los
números decimales, ya que el carácter que separa la parte entera, de la parte
decimal, puede ser un punto o una coma. Depende del idioma que tenga
configurado por defecto el sistema operativo. Si tenemos configurado español y
escribimos un número con decimales, escribirá la coma, pero si leemos un número
escrito de esta forma e intentamos asignárselo a un float nos dará error porque
está esperando un punto, que es el formato interno con el que trabaja el
compilador.
Por ejemplo el siguiente código:
public void leerVectorDiscos()
throws FileNotFoundException {
Scanner sc = new Scanner(new
File("archivo.txt"));
String fila;
String[] vectSt;
for (int j=0;j<hd.length;j++)
{
fila=sc.nextLine();
vectSt=fila.split("\t");
hd[j].setTecnologia(vectSt[0]);
hd[j].setCapacidad(Integer.parseInt(vectSt[1]));
hd[j].setVelocidad(Float.parseFloat(vectSt[2]));
}
sc.close();
}
producirá esta excepción:
Exception in
thread "main" java.lang.NumberFormatException: For input string:
"9600,00"
at
sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at
java.lang.Float.parseFloat(Float.java:452)
at
java500_1.VectorDiscos.leerVectorDiscos(VectorDiscos.java:118)
at
java500_1.Java500_1.main(Java500_1.java:36)
Java Result: 1
Una solución es utilizar la clase Numberformat, para
especificar el formato que va a tener un número decimal:
float numf;
Locale spanish = new Locale(“es”,
“ES”);
NumberFormat nf=
NumberFormat.getInstance(spanish);
numf=
nf.parse(st[2]).floatValue();
Hay que incluir los correspondientes import:
import java.text.NumberFormat;
import java.util.Locale;
De esta forma como estamos indicando que el idioma local es
español, tomará la coma como separador decimal al hacer el parseo. El código
resultante sería:
public void leerVectorDiscos()
throws FileNotFoundException , ParseException
{
Scanner sc = new Scanner(new
File("archivo.txt"));
String fila;
String[] vectSt;
for (int j=0;j<hd.length;j++)
{
fila=sc.nextLine();
vectSt=fila.split("\t");
hd[j].setTecnologia(vectSt[0]);
hd[j].setCapacidad(Integer.parseInt(vectSt[1]));
Locale spanish = new Locale(“es”, “ES”);
NumberFormat nf=
NumberFormat.getInstance(spanish);
hd[j].setVelocidad(nf.parse(vectSt[2]).floatValue());
}
sc.close();
}
Hay que tener cuidado porque crear una instancia de Locale,
no sólo cambia el separador sino también el resto de características asociadas
al idioma, como puede ser la moneda o los formatos de fecha y hora.
Una solución alternativa puede ser utilizar un objeto de la
clase DecimalFormat, derivada de NumberFormat, que toma la configuración de los
números del idioma del sistema operativo que tengamos instalado:
public void leerVectorDiscos()
throws FileNotFoundException , ParseException
{
Scanner sc = new Scanner(new
File("archivo.txt"));
String fila;
String[] vectSt;
for (int j=0;j<hd.length;j++)
{
fila=sc.nextLine();
vectSt=fila.split("\t");
hd[j].setTecnologia(vectSt[0]);
hd[j].setCapacidad(Integer.parseInt(vectSt[1]));
DecimalFormat df= new DecimalFormat();
hd[j].setVelocidad(df.parse(vectSt[2]).floatValue());
}
sc.close();
}
La clase DecimalFormat permite además especificar máscaras,
con el formato de presentación que queramos, mediante el constructor, y unos
caracteres especificados, con el carácter ‘#’, si el número no tiene una cifra
no aparecería, y con el ‘0’, aparecería un ‘0’, por ejemplo:
DecimalFormat df = DecimalFormat(“###.##”);
System.out.println (df.format (2.3)); //Sacaría 2,3
System.out.println (df.format (2.357)); //Sacaría
2,35
System.out.println (df.format (4322.3)); //Sacaría 4322,3
DecimalFormat df = DecimalFormat(“000.00”);
System.out.println (df.format (2.3)); //Sacaría 002,30
System.out.println (df.format (2.357)); //Sacaría
002,35
System.out.println (df.format (4322.3)); //Sacaría 4322,3
Existen más caracteres que pueden utilizarse en la máscara,
descritos en la API
de DecimalFormat.
No hay comentarios:
Publicar un comentario