Ver Mensaje Individual
  #2 (permalink)  
Antiguo 11/06/2015, 01:06
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 1 mes
Puntos: 204
Respuesta: Errores en código

Buenos días.

Bienvenido al foro.

Cuando tengas dudas de este estilo no es necesario, ni recomendable, que pongas todo el código. Lo que tienes que hacer es intentar presentar la menor porción de código, que a ser posible que compile, y en el que se pueda reproducir el error.

Si resulta que tu programa tiene 20k líneas de código... también lo vas a publicar así? no, verdad?

No uses variables globales

Código C++:
Ver original
  1. //declaraciones
  2. int n,i,a,z=1;
  3. ofstream archivo;//archivo de texto
  4.  
  5. empleado varempleado [1];//empleado

En pocas ocasiones estará justificado el uso de variables globales. Tu programa no es el caso.

¿Por qué es conveniente evitar su uso?

Por varias razones. Una de ellas es que estas variables existen durante toda la vida del programa, con lo que hay que ser muy cuidadoso a la hora de inicializar su valor cuando procede. Por ejemplo, si reutilizas "i" como contador y en una de estas se te olvida inicializarlo a 0 tu programa se comportará de forma extraña y te costará bastante esfuerzo encontrar el problema.

Si resulta que utilizas un valor compartido entre varias funciones lo puedes pasar como argumento, pero, en serio, intenta no usar variables globales.

Por ejemplo, archivo lo usas en la función reporte... no hay nada de malo en usar una variable local:

Código C++:
Ver original
  1. void reporte(){
  2.   // Yo, personalmente, prefiero mostrar este tipo de mensajes
  3.   // DESPUES de haber completado la operación
  4.   // Piensa que si, por algúna razón, el salvado falla el usuario va
  5.   // a pensar que la información se ha volcado al fichero correctamente
  6.   system ("cls");
  7.   cout<<"Reporte generado."<<endl;        
  8.  
  9.   ofstream archivo;
  10.   archivo.open("Empleados.txt",ios::app);
  11.   archivo<<"Datos del empleado";
  12.   archivo<<endl;
  13.   archivo.close();
  14. }

Por otro lado...

Código C++:
Ver original
  1. empleado varempleado [1];//empleado

Un array de tamaño 1????? para eso ahórrate el array, código más eficiente y más claro:

Código C++:
Ver original
  1. empleado varempleado;//empleado

main no necesita declaración

La línea 28:
Código C++:
Ver original
  1. int main( );

La puedes eliminar con mucho cariño. Las declaraciones de las funciones únicamente son necesarias en dos supuestos:
  • La función va a ser llamada desde otro fichero
  • La función va a ser llamada desde el mismo fichero pero dicha llamada se encuentra ántes que la implementación de la función

Hacer llamadas al main desde tu código es, por decirlo suavemente, un tremendo error. ¿Tú diseñarías tu casa de tal forma que para ir del baño al salon tuvieses que cruzar la puerta principal? no, verdad? main es la entrada a tu programa... no lo uses para otros propósitos.

Cuidado al declarar las variables y con los rangos

Código C++:
Ver original
  1. void agregar( )
  2. {
  3.   // ...
  4.   for (i=1; i<300; i++){
  5.     empleado varempleado [i];
  6.     varempleado[i].primer_nombre;

En ese código tienes tres problemas:
  • En cada iteración, estás creando un array de "i" elementos... nota que "i" va creciendo en cada iteración
  • con cualquier llamada a "varempleado[i]" estás accediendo a un elemento no válido
  • La última línea del ejemplo anterior no hace absolutamente nada

Intentando adivinar tus intenciones, lo que tendrías que hacer es declarar varempleado fuera del for. Si declaras la variable dentro del for ésta se pierde y se vuelve a crear con cada iteración del bucle, luego los datos almacenados con i=1 ya no estarán disponibles con i=2.

Por otro lado, en C++ los rangos para un array de tamaño N van desde 0 hasta N-1. Esto tiene como implicaciones que tu for está mal declarado, tendría que ir de 0<=i<300 en vez de 0<i<300.

Dicho esto, tu código tendría que quedar más bien así:

Código C++:
Ver original
  1. void agregar()
  2. {
  3.   empleado varempleado[300];
  4.   ofstream archivo;
  5.   archivo.open("Empleados.txt",ios::app);
  6.   for (int i=0; i<300; i++){

Ahora estás creando un arreglo de 300 elementos y el bucle va, en principio, a iterar sobre los 300 elementos.

Como te he comentado, la línea
Código C++:
Ver original
  1. varempleado[i].primer_nombre;
No hace absolutamente nada. No modificas esa variable ni tampoco usas su valor para nada. No se cual es tu intención en este punto, pero al menos así no se hace.

Cuidado con las entradas / salidas

En la función agregar():

Código C++:
Ver original
  1. cout<<"Numero de nomina:"<<endl;
  2.     cout<<varempleado[i].numero_trabajador<<endl; // <<<---- AQUI!!!
  3.     archivo<<"Numero de nomina: "<<;
  4.              varempleado[i].numero_trabajador;
  5.     archivo<<endl;

ese cout, no debería ser un cin? Se supone que quieres pedirle un dato al usuario, no?

Gestión de la ejecución

Código sacado de agregar():

Código C++:
Ver original
  1. cout<<"¿Desea agregar otro empreado?\n 1.- Si\n 2.- No\n";
  2.     cin>>q;
  3.     switch (q){
  4.      
  5.       case 1:
  6.         system ("cls");
  7.         //cout<<"Adios\n";
  8.         //opcion();
  9.         //agregar();
  10.         break;
  11.       case 2:    
  12.         system ("cls");
  13.         cout<<"Hasta luego\n";
  14.         //opcion();
  15.         main();
  16.         break;
  17.       default:
  18.         system ("cls");
  19.         cout<<"Invalido\n";
  20.     }//switch

Esto está mal planteado.

Este código está dentro de un for, luego si el usuario dice que quiere seguir introduciendo datos, simplemente deja que el bucle siga funcionando. Cuando el usuario no desee introducir más datos, símplemente añade el break y deja que la ejecución abandone el bucle, después cerrará el archivo y abandonará la función retornando al main... en el main tienes ya hecho un bucle que pregunta al usuario por la nueva operación a realizar.

El único problema que esto plantea es que si pones un break dentro de un switch, este break afecta únicamente al switch... luego el for se seguirá ejecutando. Cambia el switch por una cadena de if y ya está. Si además quieres que, ante una entrada no válida, se le siga preguntando al usuario, introduce todo este código dentro de un while

Código C++:
Ver original
  1. do
  2. {
  3.    cout<<"¿Desea agregar otro empreado?\n 1.- Si\n 2.- No\n";
  4.     cin>>q;
  5.     if( q == 2 )
  6.     {
  7.         system ("cls");
  8.         cout<<"Hasta luego\n";
  9.         break;
  10.     }
  11.     else if( q != 1 )
  12.     {
  13.         system ("cls");
  14.         cout<<"Invalido\n";
  15.     }
  16. } while( q != 1 && q != 2 );

Terminando con agregar()

Al final, en esta función estás pidiendo al usuario datos para añadir nuevos empleados a un fichero... no estás almacenando estos datos en memoria para posteriores usos y los datos los estás guardando sobre la marcha... no necesitas un array para hacer esto.

Además, el bucle no tiene por qué estar limitado a 300. Teniendo en cuenta que ya tenemos un código que nos permite salir del bucle cuando no queremos más inserciones, podemos sustituir el for por un while(true). while ejecuta el bucle mientras se cumpla la condición, como ésta será siempre cierta, la ejecución se quedará encerrada en el bucle para siempre... hasta que se encuentre con un break, que será el que hemos añadido en el punto anterior.

Código C++:
Ver original
  1. void agregar()
  2. {
  3.   empleado varempleado;
  4.   ofstream archivo;
  5.   archivo.open("Empleados.txt",ios::app);
  6.   while( true ){
  7.  
  8.     //agregar datos
  9.     cout<<"Numero de nomina:"<<endl;
  10.     cout<<varempleado.numero_trabajador<<endl;
  11.     archivo<<"Numero de nomina: "<<;
  12.              varempleado.numero_trabajador;
  13.     archivo<<endl;
  14.    
  15.     cout<<"Primer nombre:"<<endl;
  16.     cin>>varempleado.primer_nombre;
  17.     archivo<<"Primer nombre: "<<varempleado.primer_nombre;
  18.     archivo<<endl;
  19.  
  20.     // ...
  21.  
  22.     //muestra de los datos capturados
  23.     cout<<"_______________________________________________________"<<endl;
  24.     cout<<"nomina: "<<varempleado.numero_trabajador<<endl;//i<<endl;
  25.     cout<<"Primer nombre: "<<varempleado.primer_nombre<<endl;
  26.     cout<<"Segundo nombre: "<<varempleado.segundo_nombre<<endl;
  27.     // ...

Y, bueno, por no hacer este mensaje más largo, creo con esto tienes ya unas guías para corregir otros problemas de tu código... dale caña que este programa necesita un buen repaso.

Un saludo.