Java - Exception in thread "main" java.lang.NumberFormatException: For input string: ""

 
Vista:
sin imagen de perfil
Val: 27
Ha aumentado su posición en 67 puestos en Java (en relación al último mes)
Gráfica de Java

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

Publicado por pepe (11 intervenciones) el 22/02/2021 05:41:28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package actuvudad.pkg1.pkg2;
 
import java.util.Scanner;
/**
 *
 * @author aryda
 */
public class Actuvudad12 {
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
         /**
     * @param args the command line arguments
     */
        // TODO code application logic here
        int opc;
        Scanner entrada = new Scanner(System.in);
        do{
            System.out.println("*** Bienvenido!!! ***");
            System.out.println("1. Resolver un cilindro ");
            System.out.println("2. Resolver un triangulo cualquiera");
            System.out.println("3. Conversion de ºC A ºf");
            System.out.println("4. calcular la sumatoria de 1 a N");
            System.out.println("5. Calcular el promedio de N calificaciones");
            System.out.println("6. Leer la CURP y mostrar el sexo y estado de nacimiento");
            System.out.println("7. Calcular el Indice de Masa Corporal y mostrar estado de obesidad");
            System.out.println("8. Salir...");
            System.out.println("Elija su ocpcion:");
            opc = Integer.parseInt(entrada.nextLine());
            switch(opc){
                case 1:{
                    System.out.println("Resolver un cilindro");
                       resol_cilindro();
                }
                break;
                case 2:{
                    System.out.println("Resolver un triangulo");
                    Triangulo();
                }break;
                case 3:{
                System.out.println("Conversion de ºC a ºF");
                float gradosC;
                System.out.println("Ingrese sus grados Celcious");
                gradosC = entrada.nextFloat();
                System.out.println("Los grados Farenheit son :" + conversion(gradosC));
                }
                break;
            }
 
        }while(opc!=8);
    }
 
    //Métodos de la clase
    //** Area de la circunferencia
    public static void resol_cilindro(){
        double radio, Altura;
        double AreaBase;
        double volumen, PI = 3.1416;
        double a;
        Scanner entrada = new Scanner (System.in);
        System.out.println("Ingresa el radio del cilindro");
        radio = entrada.nextDouble();
        System.out.println("Ingresa la altura del cilindro");
        Altura = entrada.nextDouble();
        AreaBase = PI * radio * radio;
        volumen = AreaBase * Altura;
        System.out.println("El volumen del cilindro es" + volumen+ "cm3");
        System.out.println("El area de la base es " +AreaBase+"cm2");
    }
    //** Perimetro de la circunferencia
    static void Triangulo(){
        float base,altura,Respuesta;
        Scanner entrada = new Scanner (System.in);
        System.out.println("Ingrese la base del triangulo");
        base = entrada.nextFloat();
        System.out.println("Ingrese la altura del triangulo");
        altura = entrada.nextFloat();
        Respuesta = base * altura / 2;
        System.out.println("El area del triangulo es de " + Respuesta);
    }
    static float conversion(float C){
    float F;
    F = (C * 9 / 5) + 32;
    return (F);
    }
 
        // TODO code application logic here
    }

en el case 3 me sale la respuesta que es correcta pero me sale este error alguien que me ayude :C


Exception in thread "main" java.lang.NumberFormatException: For input string: ""
error
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Rodrigo
Val: 2.064
Plata
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

Publicado por Rodrigo (622 intervenciones) el 22/02/2021 07:45:49
Veo que usas nextFloat() y nextDouble() cuando lees valores float o double, pero cuando tienes que leer la opcion del menu, que es un entero, en vez de usar nextInt() has usado, en la linea 36

1
opc = Integer.parseInt(entrada.nextLine());

que es la que te trae el problema que muestras.

Alguna razon para no usar nextInt() ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.339
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

Publicado por Kabuto (922 intervenciones) el 22/02/2021 11:33:31
Puesto que solo se van a leer datos numéricos...

O se hacen TODAS las lecturas directamente con los métodos del Scanner:

1
2
3
entrada.nextInt();
entrada.nextDouble();
entrada.nextFloat();

o se hacen TODAS parseando lecturas con nextLine()

1
2
3
Integer.parseInt(entrada.nextLine());
Float.parseFloat(entrada.nextLine());
Double.parseDouble(entrada.nextLine());

Hay que hacerlas TODAS de un modo u otro, de lo contrario, puede ocurrir que en algún momento alguno de los parsers reciba una cadena vacía y se produzca la excepción.


En otros casos distintos, donde además de leer datos numéricos en el mismo programa también se va a requerir leer texto como String o char, entonces mejor usar los parsers para las lecturas numéricas:
1
2
3
Integer.parseInt(entrada.nextLine());
Float.parseFloat(entrada.nextLine());
Double.parseDouble(entrada.nextLine());
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 27
Ha aumentado su posición en 67 puestos en Java (en relación al último mes)
Gráfica de Java

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

Publicado por pepe (11 intervenciones) el 22/02/2021 15:36:19
Y tienen las mismas funciones las parseadas y las normales de Scanner? es decir cuando se que tengo que usar una y otra
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.339
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

Publicado por Kabuto (922 intervenciones) el 23/02/2021 00:46:57
El resultado que obtienes es el mismo.

Lo bueno de las parseadas es que al hacer lectura con nextLine(), el buffer de entrada de datos del Scanner queda siempre vacío tras cada lectura.

Con las lecturas normales no...Me explico.

Cuando tu tecleas un número, por ejemplo el 48... pulsas la tecla 4, la tecla 8 y la tecla ENTER.
Tú en pantalla ves que has tecleado 2 caracteres, el 4 y el 8..., pero en realidad has enviado 3 caracteres, pues la tecla ENTER tiene su propio carácter, llamado "retorno de carro" que es un carácter especial que no vemos en pantalla, pero sí está presente en el buffer de entrada del Scanner. Se puede representar como \r

Entonces, el Scanner se encuentra con esto en su buffer: 48\r
Ese \r, al Scanner le sirve para saber que el usuario ya ha terminado de teclear y que ya puede recoger los datos. La forma de recoger los datos, dependerá del método que hayamos llamado.

Si usamos nextInt() para leer esos datos, el Scanner cogerá los caracteres que le sirven para conformar un valor int.
Cogerá el 4, y cogerá el 8... pero no cogerá el \r, porque este carácter no sirve para construir números.

Ese carácter \r se va a quedar en el buffer del Scanner. Y aquí es cuando podemos tener problemas. Este es, de hecho, el problema que tenía tu programa.

Si seguimos haciendo lecturas de valores numéricos con nextInt(), nextDouble(), etc... no pasará nada. Estos métodos mirarán el buffer de entrada, verán que no hay caracteres con los que ellos puedan trabajar, solo el \r que no les sirve para nada..., así que esperarán a que el usuario teclee números y recogerlos.

Pero, si luego hacemos una lectura con nextLine(), tendremos un problema. nextLine() construye Strings, es decir, una línea de texto.
Y para ello cogerá cualquier carácter que se encuentre en el buffer.

Si el buffer esta vacío, como no hay nada para recoger, esperará a que el usuario teclee cosas.
Pero, si resulta que se encuentra el carácter \r, lo recogerá... y como este carácter especial simboliza el final de una línea... pues dará por finalizada la recogida de datos.
En este caso, sin que el usuario haya podido teclear nada, el Scanner devolverá una línea. Y como el único carácter que ha capturado, es el final de línea, pues esta línea devuelta estará vacía.

Esto es lo que te ocurría a ti, en esta línea:
1
opc = Integer.parseInt(entrada.nextLine());
La primera vez que se ejecuta el programa, seguramente funcionaba bien.
Pero a la siguiente vez, ese nextLine() se va a encontrar el \r que los otros métodos nextDouble() y nextFloat() han dejado pendientes en el buffer.

Entonces, ese entrada.nextLine() sí lo recoge, obtiene una cadena vacía --> ""
y esa cadena vacía se la pasa a Integer.parseInt() para que la transforme en un número entero, lo cuál es imposible.
Integer.parseInt() se encuentra con una situación excepcional, se le ha ordenado convertir una cadena vacía en número..., no sabe como actuar ante eso.., así que lanza una excepción.
Y como no hay nada que capture y controle esa excepción (más adelante te enseñarán a usar try catch ), pues el programa se detiene y muestra el error que ha ocurrido.
1
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
Esto se puede traducir como: Excepción intentando dar formato numérico, a una cadena vacía --> ""

Para evitar esto, como dije antes. Si el programa SOLO va a leer datos numéricos, entonces TODAS las lecturas se hacen con los métodos normales: nextInt(), nextFloat(), nextDouble(), nextByte(),....
Opcionalmente, se puede usar también las funciones parseadas, pero no aportan nada, excepto tener que teclear más código.
En cualquier caso, se han de hacer TODAS las lecturas iguales, o normales, o parseadas.. no mezclar.

Pero, si es un programa donde también vamos a tener que leer entradas de texto String, entonces hay que usar SOLO nextLine(), y parsear cuando sea necesario a dato numérico.


Mira, un ejemplo vale más que mil explicaciones.
Si pruebas este sencillo programa, verás que no puedes introducir el nombre.
Porque al introducir la edad con nextInt(), el siguiente nextLine() se encuentra el \r que no ha recogido el nextInt() y piensa que el usuario ya ha terminado de darle una línea, cuando en realidad no ha tenido ocasión de teclear nada.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Scanner;
 
public class Main
{
    public static void main(String[] args) {
        Scanner entrada = new Scanner(System.in);
        System.out.print("Dime edad: ");
        int edad = entrada.nextInt();
        System.out.print("Dime nombre: ");
        String nombre = entrada.nextLine();
 
        System.out.println("FIN DE PROGRAMA");
    }
}

En cambio, si la edad la introducimos con nextLine() y parseamos a int. Todo funciona bien y ya si podemos teclear el nombre.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Scanner;
 
public class Main
{
    public static void main(String[] args) {
        Scanner entrada = new Scanner(System.in);
        System.out.print("Dime edad: ");
        int edad = Integer.parseInt(entrada.nextLine());
        System.out.print("Dime nombre: ");
        String nombre = entrada.nextLine();
 
        System.out.println("FIN DE PROGRAMA");
    }
}

Porque el primer nextLine() lo coge todo, tanto los números tecleados, como el \r.
Luego construye una cadena solo con los números. El \r solo le sirve para saber donde termina la línea introducida, no lo incluye en el String, pero tampoco lo deja abandonado en el buffer. Así que la siguiente lectura con nextLine(), se encuentra el buffer vacío y entonces sí espera a que el usuario teclee la línea.

Espero que haya quedado claro. Este problema nos ha ocurrido a todos cuando empezamos con Java.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Rodrigo
Val: 2.064
Plata
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Exception in thread "main" java.lang.NumberFormatException: For input string: ""

Publicado por Rodrigo (622 intervenciones) el 23/02/2021 02:38:17
Si no te interesa la linea completa, sino la primera palabra, el programa podria usar next() en vez de nextLine() y en ese caso si' se lee el string, y no importa el Enter, por ejemplo asi:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Scanner;
 
public class Main
{
    public static void main(String[] args) {
        Scanner entrada = new Scanner(System.in);
        System.out.print("Dime edad: ");
        int edad = entrada.nextInt();
        System.out.print("Dime nombre: ");
        String nombre = entrada.next(); // <---- next aqui
 
        System.out.println( "Nombre: " + nombre + " Edad: " + edad);
        System.out.println("FIN DE PROGRAMA");
    }
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar