Es un error pensar en el flujo de entrada como si fuera una secuencia, donde pides un valor, das enter, después pides otro, das enter, y asi sucesivamente, no funciona así.
En tu caso, tu tienes la intención de recibir de primera mano un número para el menú, un valor del 1 al 3, así que supongamos que doy 1, tu crees que escribes 1, das enter y el número 1 se guarda en la variable opcion
, pero no escribiste solo 1, escribiste un 1 y un '\n'
el cual este ultimo se quedo en el buffer de entrada, para hacerme entender, mira lo que pasa con este pequeño ejemplo:
#inclide <iostream>
int main()
{
char nombre1[100];
int numero = 0;
std::cout << "Escribe un numero cualquiera: ";
std::cin >> numero;
std::cout << "Escriba su nombe: ";
std::cin.getline(nombre1, 100, '\n');
std::cout << "##################################################\n";
std::cout << "Primer numero: " << numero << "\nNombre: " << nombre1 << std::endl;
return 0;
}
Si lo ejecutas, te darás cuenta que el programa pide el número y no pide el nombre, de este pasa de largo, y cuando lo imprimes, se imprime el numero, pero el nombre queda vacio, esto paso porque quedo un '\n'
en el buffer cuando ingresaste el número, asi que para evitar esto, lo más ideal y lo correcto, es que se limpie el buffer de entrada.
esta función la utilizo para limpiar el buffer de entrada
void limpiar_buffer()
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cin.clear()
lo que hace es limpiar los flags de error del stream interno, básicamente restableciendolos a no error, si no haces esto, la siguiente instrucción cin
no se ejecutaría.
cin.ignore()
básicamente lo que hace es que ignora todo los caracteres que haya en el buffer(limpiando el buffer), hasta que encuentre un '\n'
o hasta que haya recorrido n caracteres, en este caso la longitud máxima que puede tener un stream de entrada.
Ahora con tu código, posee muchas inconsistencias,
Empecemos por la clase
Es una pésima practica de programación destapar los espacios de nombres(using namespace std
), no lo hagas, si lo haces, este pierde el chiste para lo que realmente sirven. La clase quedaría así:
class PELICULAS
{
public:
char titulo[100];
char clasificacion[100];
char duracion[100];
char horario[100];
char costo[100];
char formato[100];
void mostrar ();
void capturar ();
};
notaras que quite da
de la ultima línea de la definición de la clase, revisando tu código, le das el uso erróneo, Ademas, fácilmente tus variables de clase pueden ser string
, no veo la necesidad de utilizar string-c
o arreglos de char
, te traerá más problemas utilizar estos que utilizar los string
.
Las definiciones de las funciones de clase
No abuses tan indiscriminadamente de endl
, que este lo que hace es escribir en la salida un salto de línea('\n'
) y limpiar el buffer de salida, ademas notaras que frente a cout
, cin
y endl
hay un std::
, eso es porque no destape todo el espacio de nombre.
void PELICULAS :: capturar()
{
std::cout<< "DATOS DE LAS PELICULAS"<< "\n\n";
std::cout<< "Titulo de la pelicula: "<< "\n";
limpiar_buffer();
std::cin.getline(titulo,100);
std::cout<< "Clasificacion: "<< "\n";
std::cin.getline(clasificacion,100);
std::cout<< "Duracion: "<< "\n";
std::cin.getline(duracion,100);
std::cout<<"Horario: "<< "\n";
std::cin.getline(horario,100);
std::cout<<"Costo: "<< "\n";
std::cin.getline(costo,100);
std::cout<<"Formato: "<<std::endl;
std::cin.getline(formato,100);
}
void PELICULAS::mostrar()
{
std::cout<<"PELICULA EXISTENTE"<< "\n\n";
std::cout<<titulo<< "\n";
std::cout<< clasificacion<< "\n";
std::cout<< duracion<< "\n";
std::cout<<horario<< "\n";
std::cout<<costo<< "\n";
std::cout<<formato<<std::endl;
}
Te invito a que revises como se declaran las clases en C++, que al definir da
ahí, lo que estas haciendo es instanciando la clase PELICULAS, en un objeto global, el cual nunca utilizas realmente en tu código.
Ahora el main
la variable bucle realmente no posee una utilidad real, ¿Por qué no utilizas solamente la variable opción para gestionar el bucle?, ademas, al definir la clase PELICULAS
en cada case
, estas limitando su ámbito solo a ese case
, quiere decir que cuando el flujo del programa salga del case
, la memoria de esa clase sera limpiada y se perderá toda la información que esta contenga, puedes notar donde yo definí a PELICULAS
.
No utilices a system
, estas llamando a todo el sistema solo para que te limpie la consola y acostumbrarse a utilizarlo puede ocasionar fugas de seguridad en un programa serio que realices en el futuro, te pongo un ejemplo, que tal que yo cambiara a cls
por un programa malicioso, y que tu programa tenga permisos de administrador para correr, implícitamente le das permiso a ese programa que tu piensas que es cls
. No te acostumbres a utilizarlo.
int main()
{
int opcion = 0;
PELICULAS datos;
do
{
std::cout<<"MENU PELICULAS"<< "\n\n";
std::cout<<"1. Capturar"<< "\n";
std::cout<<"2. Mostrar"<< "\n";
std::cout<<"3. Salir"<< std::endl;
std::cout<<"ELIGE UNA OPCION: ";
std::cin >> opcion;
switch(opcion)
{
case 1:
{
datos.capturar();
break;
}
case 2:
{
datos.mostrar();
break;
}
case 3:
{
std::cout<< "\n" <<"G R A C I A S"<<std::endl;
break;
}
default:
{
std::cout<<"O P C I O N N O V A L I D A"<<std::endl;
}
}
}
while (opcion != 3);
return 0;
}
Las cabeceras que utilizo son <iostream>
y <limits>
, no necesitas a <windows.h>
, no la estas utilizando para nada en absoluto.