Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: santiagolo en 6 Marzo 2014, 01:12 am



Título: Error c++
Publicado por: santiagolo en 6 Marzo 2014, 01:12 am
Hola!, podrían ayudarme a encontrar el error de este programa?


Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<ctype.h>
  4. #include<string.h>
  5.  
  6. int a;
  7. char nombres[1000][25],apellidos[1000][30];
  8. FILE*arch;
  9. int cargar_arch(){
  10.                  if(fopen("dato.txt","r")){
  11.                  arch=fopen("dato.txt","r");
  12.                  fscanf(arch,"%i",&a);
  13.                  for(int c=0;c<a;c++){
  14.                                        fprintf(arch,"%s\n",nombres[c]);
  15.                                        fprintf(arch,"%s\n",apellidos[c]);
  16.                                        }
  17.                  fclose(arch);
  18.                  return 1;
  19.                  }                
  20.                  else if (!fopen("dato.txt","r")){
  21.                                                   return 0;
  22.                                                   }
  23.                          }
  24. void cargar(){
  25.              printf("Ingrese cantidad de empleados\n");
  26.              printf("Cantidad: ");
  27.              do{
  28.                 scanf("%i",&a);
  29.                 }
  30.                while(a<=0||a>=1000);
  31.             for(int c=0;c<a;c++){system("cls");
  32.                                  printf("Empleado Numero %i\n",c+1);
  33.                                  printf("Nombre: ",nombres[c]);
  34.                                  scanf("%s",&nombres[c]);
  35.                                  printf("Apellido: ",apellidos[c]);
  36.                                  scanf("%s",&apellidos[c]);
  37.                                  system("cls");
  38.                                  }
  39.  
  40.             }
  41. int guardar_arch(){
  42.                   arch=fopen("dato.txt","w");
  43.                   fprintf(arch,"%i\n",&a);
  44.                   for(int c=0;c<a;c++){
  45.                                        for(int c2=0;c2<a;c2++){
  46.                                                                fprintf(arch,"%s\n",&nombres[c]);
  47.                                                                fprintf(arch,"%s\n",&apellidos[c]);
  48.                                                                }
  49.                                        }
  50.  
  51.                   fclose(arch);
  52.                   }
  53.  
  54. main(){
  55.       int op;
  56.       char aux[25];
  57.       if(cargar_arch()==1){printf("Se cargaron datos anteriores\n");}
  58.       else printf("No hay datos anteriores\n");
  59.       do{
  60.          printf("1)Cargar\n");
  61.          printf("2)Ver\n");
  62.          printf("3)Salir\n");
  63.          printf("Opcion: ");
  64.          scanf("%i",&op);
  65.           switch(op){
  66.                      case 1:
  67.                      cargar();      
  68.                      break;
  69.                      case 2:
  70.                      printf("EMPLEADOS\n\n");
  71.                       for(int con=0;con<a;con++){
  72.                                                  for(int con2=0;con2<a;con2++){
  73.                                                                                if(strcmp(apellidos[con],apellidos[con2])<0){
  74.                                                                                strcpy(aux,apellidos[con]);
  75.                                                                                strcpy(apellidos[con],apellidos[con2]);
  76.                                                                                strcpy(apellidos[con2],aux);
  77.                                                                                strcpy(aux,nombres[con]);
  78.                                                                                strcpy(nombres[con],nombres[con2]);
  79.                                                                                strcpy(nombres[con2],aux);
  80.                                                                                                         }
  81.                                                                               }
  82.                                                }
  83.                       for(int con=0;con<a;con++){
  84.                                                  printf("%s ,%s\n",apellidos[con],nombres[con]);
  85.                                                 }                                
  86.                       break;
  87.                       case 3:
  88.                       guardar_arch();
  89.                       break;
  90.                       system("cls");
  91.                       system("pause");
  92.                       }
  93.   }
  94.   while(op!=3);
  95. }

Salta error en el segundo corchete y no entiendo porque!
Muchas gracias


Título: Re: Error c++
Publicado por: engel lex en 6 Marzo 2014, 01:15 am
podrías publicar exactamente el error que salta? los errores son útiles porque dicen cual fue el error y sabiendo el mismo puedes arreglarlo, lo estoy compilando en un compilador online y compila bien


Título: Re: Error c++
Publicado por: nolasco281 en 6 Marzo 2014, 07:20 am
No se si a esto te referis

Otra cosa muy importante comenta tu codigo escribir
Código
  1. //No cuesta mucho : )

1. No ha creado el archivo .txt pero si hace su funcion.

(http://1.bp.blogspot.com/-1InFOuvxkVg/UxgR0WN8F9I/AAAAAAAAAi8/urbrcNXVLpY/s1600/Untitled.png)

2. salgo de la programa me crea el .txt pero al volver entrar me salta este error

(http://3.bp.blogspot.com/-S4TtfbiOj2w/UxgSlLYacEI/AAAAAAAAAjE/bygGb1MA1i0/s1600/Untitled1.png)

3. es el error que te salta a ti, y como comenta engelx podrias ser un poco mas explicito.

Una pregunta por que creas arreglos bidimencionales para nombre y apellido? revisa eso.

Saludos.


Título: Re: Error c++
Publicado por: eferion en 6 Marzo 2014, 09:14 am
Varias cosas:

1. int a???? que co** es a????, vale, si inviertes unos minutillos en analizar el código descubres que a es una variable global que la usas para almacenar la cantidad de registros... ¿es necesario llamarla a?? ¿no había un nombre un poco más apropiado? no se algo quizás del tipo 'numeroDeRegistros'. No se, yo creo que si alguien se encuentra con una variable que se llama 'numeroDeRegistros' se hace una idea bastante aproximada del uso que tiene esa variable y puede llegar a entender el código con más rapidez.

2. No uses variables globales. No cuesta nada poner un argumento más en las funciones y con eso consigues que seguir el programa sea más sencillo.

3. Por si no te has dado cuenta, no has inicializado tu querida 'a'... si ejecutas el programa y no pasas por la opción 1 el resultado no te va a gustar.

4. En cargar_arch... si falla la carga del archivo TAMPOCO actualizas el valor de 'a'...

5. ¿Por qué el buffer de nombres es de 25 y el de apellidos de 30?? ¿por qué 'aux' es de 25 si también va a almacenar apellidos? Lo mejor para evitar este tipo de inconsistencias es usar macros para definir valore fijos:

Código
  1. #define MAX_REGS 1000
  2. #define LONG_REG 30
  3.  
  4. char nombres[MAX_REGS][LONG_REG],apellidos[MAX_REGS][LONG_REG];
  5.  
  6. // ...
  7.  
  8. char aux[LONG_REG];
  9.  
  10. // ...

6. fscanf y scanf pueden provocar desbordamiento de buffer si intentas cargar una cadena más grande que el buffer... en tu caso 25 o 30 caracteres... deberías hechar un vistazo a |Lo que no hay que hacer en C/C++. Nivel basico| (http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html).

7. Da la sensación de que en la opción 2 intentas ordenar el vector antes de mostrarlo... No hace falta comprobar un registro contra sí mismo para hacerlo.

Código
  1. for(int con=0;con<a;con++)
  2. {
  3.  for(int con2=con+1;con2<a;con2++)
  4.  {
  5.    if(strcmp(apellidos[con],apellidos[con2])<0)
  6.    {
  7.      strcpy( aux, apellidos[con] );
  8.      strcpy( apellidos[con], apellidos[con2] );
  9.      strcpy( apellidos[con2], aux );
  10.      strcpy( aux, nombres[con] );
  11.      strcpy( nombres[con], nombres[con2] );
  12.      strcpy( nombres[con2], aux );
  13.    }
  14.  }
  15. }

Si además metes ese código repetitivo en una función, el código se simplifica:

Código
  1. void SwapStrings( char* string1, char* string2 )
  2. {
  3.  char aux[30];
  4.  strcpy( aux, string1 );
  5.  strcpy( string1 , string2  );
  6.  strcpy( string2 , aux );
  7. }
  8.  
  9. // ...
  10.  
  11. for(int con=0;con<a;con++)
  12. {
  13.  for(int con2=con+1;con2<a;con2++)
  14.  {
  15.    if(strcmp(apellidos[con],apellidos[con2])<0)
  16.    {
  17.      SwapStrings( apellidos[con], apellidos[con2] );
  18.      SwapStrings( nombres[con], nombres[con2] );
  19.    }
  20.  }
  21. }

Y no parece buena idea que este código se ejecute SIEMPRE que se vayan a visualizar los registros... deberías aislar este código en una función y llamarlo después de que el usuario introduzca los datos y después de cargar los datos del archivo.

8. Tu programa no está en C++, está en C puro y duro.

9. Al guardar tienes el siguiente código:

Código
  1. for(int c=0;c<a;c++)
  2. {
  3.  for(int c2=0;c2<a;c2++)
  4.  {
  5.    fprintf(arch,"%s\n",&nombres[c]);
  6.    fprintf(arch,"%s\n",&apellidos[c]);
  7.  }
  8. }

el bucle de c2 no solo es redundante, sino que tiene un efecto dañino y es que la lista va a aparecer repetida en el archivo tantas veces como elementos tengas en la lista, 2 nombres aparecerán 2 veces, 20 nombres aparecerán 20 veces cada uno... 1000 nombres....

10. El siguiente código está mal:

Código
  1. printf("Nombre: ",nombres[c]);
  2. scanf("%s",&nombres[c]);
  3. printf("Apellido: ",apellidos[c]);
  4. scanf("%s",&apellidos[c]);

Por varios motivos:

* para sacar el nombre y los apellidos por pantalla te falta '%s':

Código
  1. printf( "Nombre: %s", nombres[c] );

Y lo mismo para los apellidos... además si no añades ni espacios ni saltos de línea te van a salir pegados y el efecto es feo.

Otra cosa es que no desees mostrar el nombre que había anteriormente en la lista, lo cual es más lógico... en ese caso te puedes ahorrar pasar por argumentos en el printf el nombre y los apellidos:

Código
  1. printf("Nombre: " );

* Los scanf, en el caso de vectores, matrices y punteros en general, no necesitan el '&'. Esto es así porque scanf necesita punteros para almacenar los valores... y un vector es un puntero... no necesitas pasar referencias:

Código
  1. scanf( "%s", nombres[c] );

11. Fíjate en la función carga_arch:

Código
  1. int cargar_arch()
  2. {
  3.  if(fopen("dato.txt","r"))
  4.  {
  5.    // ...
  6.    return 1;
  7.  }                
  8.  else if (!fopen("dato.txt","r"))
  9.  {
  10.    return 0;
  11.  }
  12. }

No tiene sentido que intentes abrir dos veces el archivo, porque... ¿Y si falla la primera vez pero funciona la segunda? el else se inventó precisamente para tratar el caso del "y si no...". Y no sufras por esto, el compilador, a diferencia del programador, no se confunde con estas cosas.

Código
  1. int cargar_arch()
  2. {
  3.  if(fopen("dato.txt","r"))
  4.  {
  5.    // ...
  6.    return 1;
  7.  }                
  8.  else
  9.  {
  10.    return 0;
  11.  }
  12. }

12. En guardar_arch...

Código
  1. arch=fopen("dato.txt","w");
  2. fprintf(arch,"%i\n",&a);

¿Y si no se puede abrir el archivo? Aprende y aplica esta regla de oro: "Valida que los punteros son válidos antes de usarlos".

Y bueno, con esto creo que a grandes rasgos esto es todo. Espero que no se me haya olvidado nada.

Un saludo.


Título: Re: Error c++
Publicado por: rir3760 en 6 Marzo 2014, 16:36 pm
Espero que no se me haya olvidado nada.
Hay un error lógico en este bloque:
Código
  1. int cargar_arch()
  2. {
  3.   if (fopen("dato.txt","r")){
  4.      arch = fopen("dato.txt","r"); /* modo "r", lectura */
  5.      fscanf(arch, "%i", &a);       /* OK */
  6.  
  7.      for (int c = 0; c < a; c++){
  8.         fprintf(arch, "%s\n", nombres[c]);   /* <== */
  9.         fprintf(arch, "%s\n", apellidos[c]); /* <== */
  10.      }
  11.      fclose(arch);
  12.  
  13.      return 1;
  14.   }
Considerando el estado del programa tal vez haya mas (no lo revise a fondo).

Un saludo


Título: Re: Error c++
Publicado por: eferion en 6 Marzo 2014, 16:47 pm
Cierto... no me había fijado en las dos llamadas consecutivas.

Bien visto.


Título: Re: Error c++
Publicado por: xaps en 6 Marzo 2014, 20:00 pm
Y bueno, con esto creo que a grandes rasgos esto es todo. Espero que no se me haya olvidado nada.

Un saludo.

No quiero ni pensar que habrías escrito si hubieras entrado en detalle  :laugh:


Título: Re: Error c++
Publicado por: eferion en 7 Marzo 2014, 08:03 am
No quiero ni pensar que habrías escrito si hubieras entrado en detalle  :laugh:

Jajajajaja.

Bueno, lo cierto es que cuando ya has puesto una docena de comentarios con cosas a corregir sobre un programa tan corto no tiene sentido seguir poniendo cosas porque entonces los comentarios se empiezan a solapar. Tampoco es cuestión de echar para atrás a nadie.

desde luego ya te digo yo que si fuese profesor, visto lo visto, me centraría bastante en conseguir que la gente aprendiese a estructurar un programa... me da la sensación que la inmensa mayoría únicamente buscan que el programa funcione y eso me parece un error.


Título: Re: Error c++
Publicado por: xaps en 7 Marzo 2014, 19:44 pm
Jajajajaja.

Bueno, lo cierto es que cuando ya has puesto una docena de comentarios con cosas a corregir sobre un programa tan corto no tiene sentido seguir poniendo cosas porque entonces los comentarios se empiezan a solapar. Tampoco es cuestión de echar para atrás a nadie.

desde luego ya te digo yo que si fuese profesor, visto lo visto, me centraría bastante en conseguir que la gente aprendiese a estructurar un programa... me da la sensación que la inmensa mayoría únicamente buscan que el programa funcione y eso me parece un error.
El problema está en que muchas veces lo único que se busca es eso. Yo estoy estudiando ingeniería informática y una compañera que ha venido de telecomunicaciones me comentó que allí cuando programaban lo único que les pedían era que el programa funcionase, y que la organización y eficiencia del código eran completamente secundarias. Supongo que también dependerá del lugar en el que estudies y de lo que estudies, pero a mi me crujen si les entrego un código con nombres de variables como las de este señor.


Título: Re: Error c++
Publicado por: eferion en 7 Marzo 2014, 20:19 pm
El problema está en que muchas veces lo único que se busca es eso. Yo estoy estudiando ingeniería informática y una compañera que ha venido de telecomunicaciones me comentó que allí cuando programaban lo único que les pedían era que el programa funcionase, y que la organización y eficiencia del código eran completamente secundarias. Supongo que también dependerá del lugar en el que estudies y de lo que estudies, pero a mi me crujen si les entrego un código con nombres de variables como las de este señor.

En mi universidad pasaba igual... te daban un guión y el resto era cosa tuya... ellos al final solo querían ver que funcionaba y que no había lagunas de memoria... así pasa que luego te encuentras proyectos reales que te dan ganas de arrancarte los ojos.