[ Foro de C# ]

Cadena de entrada no tiene el formato correcto

07-Dec-2013 22:07
Adolfo Unturbe
4 Respuestas

Antes que nada me presento, soy estudiante de Desarrollo de Aplicaciones Web y estaba haciendo una práctica para clase cuando me he topado con este problema.
cuando ejecutamos el programa y le damos a la opción 1 del menu y pulsamos enter nos lleva hacia la función Altas. En dicha función se pide que ingreses el Id. del alumno. Cuando lo ingresas te comprueba, mediante una función externa si el valor del id introducido no existe y si existe te muestra un mensaje de error. Bien hasta aquí bien, pero cuando pulsamos enter cuando nos sale dicho mensaje de error entonces nos vuelve al menú (que es exactamente lo que quiero que haga el programa, volver al menú para que el usuario que esté usando el programa vuelva a entrar a la función altas y seguir dando de alta a más alumnos). El caso es que cuando vuelve al menú me salta el siguiente error: "La cadena de entrada no tiene el formato correcto." justo en la línea 131, que es donde se pide al usuario que ingrese una opción del menú.
Aquí les dejo el pastebin del codigo fuente de mi programa. Les agradecería muchísimo que me enseñaran a solventar este error puesto que tengo el examen pronto.
http://pastebin.com/SJa0eE2F

Muchas Gracias por adelantado, y un saludo!!!


07-Dec-2013 23:10
Nacho Cabanes (+84)

En primer lugar, incluyo aquí tu fuente para que quede más claro de qué hablamos (¿quién necesita PasteBin en un foro de programación que tiene sintaxis en colores para los fuentes? ;-D) :


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
 
namespace Practica1MenuNotas
{
    //Declaramos como pública la estructura de la tabla que vamos a hacer después.
    struct dato
    {
        public int numero;
        public string nombre;
        public double nota;
    }
    class Program
    {
        //static int numero = 1;
        static void Main(string[] args)
        {
           
            dato[] tabla = new dato[5];
            //Dclaro primero la variable op dentro de la función Main y seguidamente hago un
            //do-while en el cual llamo al menú para que se efectúe
            //el bucle que repite el menú si no pulsamos 0.
            //Seguidamente hago un switch que es el que recogerá las diferentes llamadas a las funciones
            //cuando introduzca el número que está en el menú indicado.
            /*int op = Menu();*/
            //Llamo a la función opciones que va a recibir tabla.
            opciones (tabla);
            /*Console.ReadLine();*///NO HACE FALTA
        }
        //Aquí he conseguido meter el switch dentro de una función aparte.
        //Lo que he hecho ha sido crear una función estática que no devuelva ningún valor.
        //static void opciones y dentro de opciones lo que hacemos es meterle los parámetros a la tabla dato.
        //Luego en la función principal Main llamo a la funciójn opciones.
        static void opciones(dato [] tabla)
        {
            /*int i = 0;*/
            int op;
            do
            {
                op = Menu();
                switch (op)
                {
                    case 1:
                        Console.Write("<------------>\n");
                        Console.Write("<- 1. ALTAS ->\n");
                        Console.Write("<------------>\n");
                        Altas(tabla);//Llamo a la función de altas.
                        /*Console.ReadLine();*/
                        break;
                    case 2:
                        Console.Write("<------------>\n");
                        Console.Write("<- 2. BAJAS ->\n");
                        Console.Write("<------------>\n");
                        bajas(tabla);//Llamo a la función de bajas.
                        /*Console.ReadLine();*/
                        break;
                    case 3:
                        Console.Write("<--------------------->\n");
                        Console.Write("<- 3. MODIFICACIONES ->\n");
                        Console.Write("<--------------------->\n");
                        modificaciones(tabla);//Llamo a la función de modificaciones.
                        /*Console.ReadLine();*/
                        break;
                    case 4:
                        Console.Write("<---------------->\n");
                        Console.Write("<- 4. CONSULTAS ->\n");
                        Console.Write("<---------------->\n");
                        consultas(tabla);
                        /*Console.ReadLine();*/
                        break;
                    case 5:
                        Console.Write("<-------------->\n");
                        Console.Write("<- 5. ORDENAR ->\n");
                        Console.Write("<-------------->\n");
                        Console.ReadLine();
                        break;
                    case 6:
                        Console.Write("<-------------------------->\n");
                        Console.Write("<- 6. BÚSQUEDA SECUENCIAL ->\n");
                        Console.Write("<-------------------------->\n");
                        Console.ReadLine();
                        break;
                    case 7:
                        Console.Write("<----------------------->\n");
                        Console.Write("<- 7. BÚSQUEDA BINARIA ->\n");
                        Console.Write("<----------------------->\n");
                        Console.ReadLine();
                        break;
                    case 8:
                        Console.Write("<-------------->\n");
                        Console.Write("<- 8. MEZCLAR ->\n");
                        Console.Write("<-------------->\n");
                        Console.ReadLine();
                        break;
                }
            } while (op != 0);
        }
        //FUNCIÓN Menu.
        static int Menu()
        {
            //int op = 0;
            //Limpiamos Pantalla.
            Console.Clear();
            //Aquí el menú.
            Console.WriteLine("<-----------Menú de opciones----------->");
            //Thread.Sleep(300);
            Console.WriteLine(" |    1- Altas                        |");
            //Thread.Sleep(320);
            Console.WriteLine(" |    2- Bajas                        |");
            //Thread.Sleep(325);
            Console.WriteLine(" |    3- Modificaciones               |");
            //Thread.Sleep(330);
            Console.WriteLine(" |    4- Consultas                    |");
            //Thread.Sleep(335);
            Console.WriteLine(" |    5- Ordenar                      |");
            //Thread.Sleep(340);
            Console.WriteLine(" |    6- Búsqueda secuencial          |");
            //Thread.Sleep(345);
            Console.WriteLine(" |    7- Búsqueda Binaria             |");
            //Thread.Sleep(350);
            Console.WriteLine(" |    8- Mezclar                      |");
            //Thread.Sleep(355);
            Console.WriteLine(" |    0- Salir                        |");
            //Thread.Sleep(360);
            Console.WriteLine("<-------------------------------------->");
            //Thread.Sleep(365);
            Console.Write("--->Seleccione una opción del menú: ");
            int op = Convert.ToInt32(Console.ReadLine());
            return (op);
        }//FIN FUNCIÓN MENU
 
        //Función que revisa si el id ingresado está o no repetido.
        static int comprobacion(dato[] tabla, int comprueba)
        {
            int i;
            for (i = 0; i < tabla.Length; i++)
            {
                if (tabla[i].numero == comprueba)
                {
                    return i;
                }
            }
            return -1;
        }
 
        //  1)  INICIO FUNCION ALTAS
        static void Altas(dato[] tabla)
        {
            int comprueba,check,c=1;
            Console.Clear();
            for (int i = 0; i < tabla.Length;i++)
                if (tabla[i].numero == 0)
                {
                    Console.Write("Inserte el Id. del alumno: ");
                    comprueba = Convert.ToInt32(Console.ReadLine());
                    check = comprobacion(tabla, comprueba);
                    if (check == -1)
                    {
                        while (c != 0)
                        {
                            tabla[i].numero = comprueba;
                            c = 0;
                        }
                    }
                    else
                    {
                        Console.Write("....¡ERROR!....   No es posible ingresar el mismo id. para varios alumnos.\n pulse una tecla para continuar\n");
                        Console.Read();
                        break;
                    }
                    Console.Write("\n Introduzca nombre: ");
                    tabla[i].nombre = Console.ReadLine();
                    Console.Write("\n Introduzca nota: ");
                    tabla[i].nota = Convert.ToDouble(Console.ReadLine());
                }
                else
                {
                    Console.Write("\nSe ha alcanzado el número máximo de datos. \n\n     TABLA LLENA.... Saliendo al menú...");
                    Console.ReadLine();
                    break;
                }
            /*Console.Write("Inserte el Id. del alumno: ");
            comprueba = Convert.ToInt32(Console.ReadLine());
            i = comprobacion(tabla, comprueba);
            if (i == -1)
            {
                for (i = 0; i < tabla.Length && c != 0; i++)
                {
                    if (tabla[i].numero == 0)
                    {
                        tabla[i].numero = comprueba;
                        c = 0;
                    }
                }
            }
            else
            {
                Console.Write("....¡ERROR!....   No es posible ingresar el mismo id. para varios alumnos.\n pulse una tecla para continuar");
                Console.ReadLine();
            }
            for (i = 0; i < tabla.Length; i++)
            {
 
            }
            Console.Write("Escriba el nombre del alumno: ");*/
            //Lo de arriba lo dejo comentado de forma provisional.... Lo de abajo lo mismo...
 
            /*for (int i = 0; i < tabla.Length; i++)
            {
                if (tabla[i].numero == 0)
                {
                    /*string confirmacion;*/
           //         Console.Write("Introduzca el Id. del alumno: ");
                    //tabla[i].numero = Convert.ToInt32(Console.ReadLine());
                    /*Console.Write("\n {0}", i);*/
           /*         Console.Write("\n Introduzca nombre: ");
                    tabla[i].nombre = Console.ReadLine();
                    Console.Write("\n Introduzca nota: ");
                    tabla[i].nota = Convert.ToDouble(Console.ReadLine());
                    numero++;
                    /*if (numero <= tabla.Length)
                    {
                        Console.Write("\n¿Desea continuar?(s,n)");
                        confirmacion = Console.ReadLine();
                        if (confirmacion == "n")
                        {
 
                            break;
                        }
                    }*/                    
           /*     }
                else
                {
                    Console.Write("\nSe ha alcanzado el número máximo de datos. \n\n     TABLA LLENA.... Saliendo al menú...");
                    Console.ReadLine();
                    break;
                }
            }
            /*return (j);*/
        }//FIN FUNCION ALTAS
        //  2)  INICIO FUNCION BAJAS
        static void bajas(dato[] tabla)
        {
            Console.Write("Introduzca el id del alumno que quiere eliminar de la tabla:");
            int n = Convert.ToInt32(Console.ReadLine());
            for (int i = 0; i < tabla.Length; i++)
            {
                if (n == tabla[i].numero)
                {
                    tabla[i].numero = 0;
                }
            }
        }//FIN FUNCION BAJAS
        //  3)  INICIO FUNCIÓN MODIFICACIONES
        static void modificaciones(dato[] tabla)
        {
            Console.Write("Introduzca el id del alumno que desea modificar:");
            int modif = Convert.ToInt32(Console.ReadLine());
            for (int i = 0; i < tabla.Length; i++)
            {
                if (modif == tabla[i].numero)
                {
                    Console.Write("Introduzca el nuevo nombre:");
                    tabla[i].nombre = Console.ReadLine();
                    Console.Write(".");
                    Thread.Sleep(300);
                    Console.Write(".");
                    Thread.Sleep(350);
                    Console.Write(".");
                    Thread.Sleep(360);
                    Console.Write(".");
                    Thread.Sleep(365);
                    Console.Write(".");
                    Thread.Sleep(370);
                    Console.Write(" ¡Acción Realizada Correctamente!");
                    Console.Write("\n\n Presione una tecla para continuar y modificar la nota...");
                    Console.ReadLine();
                    Console.Write("Introduzca la nueva nota:");
                    tabla[i].nota = Convert.ToDouble(Console.ReadLine());
                    Console.Write(".");
                    Thread.Sleep(300);
                    Console.Write(".");
                    Thread.Sleep(350);
                    Console.Write(".");
                    Thread.Sleep(360);
                    Console.Write(".");
                    Thread.Sleep(365);
                    Console.Write(".");
                    Thread.Sleep(370);
                    Console.Write(" ¡La nota ha sido cambada correctamente!");
                    Console.Write("\n Acaba de cambiar los datos del alumno que ha seleccionado.\n Pulse una tecla para volver al menú");
                }
            }
        }
        //  4)  INICIO FUNCION CONSULTAS
        static void consultas(dato[] tabla)
        {
            for (int i = 0; i < tabla.Length; i++)
            {
                if (tabla[i].numero != 0)
                {
                    Console.Write("Id.  |   Nombre   |   Nota\n");
                    Console.Write("----------------------------\n");
                    Console.Write(tabla[i].numero + "   || " + tabla[i].nombre + "           || " + tabla[i].nota + "\n"); // muestra la tabla.
                    Thread.Sleep(500);
                    Console.ReadLine();
                }
            }
        }//FIN FUNCION CONSULTAS
    }
}



Tu línea 131 es perfectamente válida:


int op = Convert.ToInt32(Console.ReadLine());


Luego el problema viene de otro sitio. Puede ayudarte el descomponer esa línea en dos, para comprobar lo que está pasando:


string texto = Console.ReadLine();
Console.WriteLine("Has escrito -{0}-", texto);
int op = Convert.ToInt32(texto);


(o también puedes usar el depurador de Visual Studio, para ver el valor de esa cadena).

Verás que el texto que recibes no es sólo un número. El problema está en otra línea, la 171, que dice:


Console.Read();


No deberías usar "Console.Read()", porque puede dejar algo en el buffer del teclado. Utiliza siempre Console.ReadLine().


07-Dec-2013 23:16
Adolfo Unturbe

Muchas gracias por tu rápida respuesta y por tu ayuda, ahora enciendo el pc, pruebo lo que me has comentado y te comento a ver qué tal me ha ido. :)


07-Dec-2013 23:20
Nacho Cabanes (+84)

Irá bien. ;-)

Es un fallo frecuente. También pasa en C con los "getchar" y en ocasiones con los "scanf", pasa en Pascal con los "Read", puede pasar en C++ si usas "cin" y un dato de tipo char, etc. Es un tipo de órdenes que están pensadas para leer varios datos en secuencia, no para leer un único dato desde teclado, porque puede que (como mínimo) la pulsación de la tecla "Intro" no sea absorbida y se quede en el buffer de teclado, provocando lecturas erróneas a partir de ese punto.


07-Dec-2013 23:28
Adolfo Unturbe

Acabo de probar lo que me has dicho y, en efecto funciona correctamente. De nuevo muchísimas gracias. Además la explicación que me has dado sobre el Console.Read(); me viene como anillo al dedo ya que así lo tomaré en cuenta para futuras ocasiones. Ahora podré seguir arreglando más fallitos que tengo en el programa y poniéndolo a punto.
¡¡Gracias!! :D






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)