Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DarkSorcerer en 13 Enero 2014, 23:38 pm



Título: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: DarkSorcerer en 13 Enero 2014, 23:38 pm
Saludos comunidad, tengo un error muy gordo acerca de los structs en C, resulta que quiero crear personas usando structs en vez de crear una clase (paradojicamente, empecé al revés, es decir, de C++ a C)

La cosa es que cree una estructura que representa a una persona, tiene un nombre, apellido paterno, apellido materno, edad y rut (numero de identificación), la cosa es que en el main quiero crearlos y através de una función es la que imprime por pantalla los valores de cada persona para ahorrar lineas de código, pero no me funciona, me vi obligado a hacerlo en el main y también me sale error, les pongo mi código para que me puedan ayudar porfavor. Estoy usando DevC++. En el fondo del post se encuentra una captura del error.

Código
  1. #include <stdio.h>
  2. #include <windows.h>
  3.  
  4. struct persona{
  5.  
  6.    char nombre[20];
  7.    char apellidoP[20];
  8.    char apellidoM[20];
  9.    char rut[10];
  10.    int edad;        
  11.  
  12. }
  13.  
  14. void desplegarValores(struct persona p){
  15.  
  16.    printf("Nombre: %s\n",p.nombre);
  17.    printf("Apellido paterno: %s\n",p.apellidoP);
  18.    printf("Apellido materno: %s\n",p.apellidoM);
  19.    printf("Rut: %s\n",p.rut);
  20.    printf("Edad: %i\n\n",p.edad);    
  21.  
  22. }
  23.  
  24. int main(){
  25.  
  26.    struct persona persona1;
  27.    struct persona persona2;
  28.    struct persona persona3;
  29.  
  30.    persona1.nombre = "Rodrigo";
  31.    persona1.apellidoP = "Saavedra";
  32.    persona1.apellidoM = "Pizarro";
  33.    persona1.rut = "ASDF-1";
  34.    persona1.edad = 23;
  35.  
  36.    persona2.nombre = "Jorge";
  37.    persona2.apellidoP = "Muñoz";
  38.    persona2.apellidoM = "Cardenas";
  39.    persona2.rut = "QWERT-1";
  40.    persona2.edad = 27;
  41.  
  42.    persona3.nombre = "Francisco";
  43.    persona3.apellidoP = "Sanchez";
  44.    persona3.apellidoM = "Villagra";
  45.    persona3.rut = "ZXCV-3";
  46.    persona3.edad = 56;
  47.  
  48.    desplegarValores(persona1);
  49.    desplegarValores(persona2);
  50.    desplegarValores(persona3);
  51.  
  52.    printf("Nombre: %s\n",persona1.nombre);
  53.    printf("Apellido paterno: %s\n",persona1.apellidoP);
  54.    printf("Apellido materno: %s\n",persona1.apellidoM);
  55.    printf("Rut: %s\n",persona1.rut);
  56.    printf("Edad: %i\n\n",persona1.edad);
  57.  
  58.    printf("Nombre: %s\n",persona2.nombre);
  59.    printf("Apellido paterno: %s\n",persona2.apellidoP);
  60.    printf("Apellido materno: %s\n",persona2.apellidoM);
  61.    printf("Rut: %s\n",persona2.rut);
  62.    printf("Edad: %i\n\n",persona2.edad);
  63.  
  64.    printf("Nombre: %s\n",persona3.nombre);
  65.    printf("Apellido paterno: %s\n",persona3.apellidoP);
  66.    printf("Apellido materno: %s\n",persona3.apellidoM);
  67.    printf("Rut: %s\n",persona3.rut);
  68.    printf("Edad: %i\n\n",persona3.edad);
  69.  
  70.    system("PAUSE");
  71.    return 0;    
  72.  
  73. }
  74.  

(http://s2.subirimagenes.com/imagen/previo/thump_8773049error.png)


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: xiruko en 14 Enero 2014, 00:01 am
A ver, primer error es que te falta un ';' al final de la declaración del struct:

Código
  1. struct persona
  2. {
  3.    char nombre[20];
  4.    char apellidoP[20];
  5.    char apellidoM[20];
  6.    char rut[10];
  7.    int edad;        
  8. };

Segundo, en C, una vez pasada la declaración de las variables, no se pueden asignar las cadenas de esta manera:

Código
  1. persona1.nombre = "Rodrigo";
  2. persona1.apellidoP = "Saavedra";

En lugar de eso, deberías hacerte alguna función para copiar carácter a carácter o usar, por ejemplo, la función strncpy() (http://www.cplusplus.com/reference/cstring/strncpy/) de la librería 'string.h'. Quedaría algo así:

Código
  1. #include <string.h>
  2.  
  3. char nombre1[] = "Rodrigo";  // aqui si que se puede porque es en el momento de la declaracion
  4. strncpy(persona1.nombre, nombre1, strlen(nombre1));  // en tiempo de ejecucion hay que hacerlo asi

También puedes inicializar las variables del tipo de tu estructura al momento de declararlas:

Código
  1. struct persona persona1 = {"Rodrigo", "Saavedra", "Pizarro", "ASDF-1", 23};

edito: mirando el código, sería una buena práctica que pasaras un puntero de tu estructura a la función 'desplegarValores' en lugar de la estructura en sí, ya que así evitarías que se hiciera una copia local de ella. Si además no quieres que en la función se modifique el valor de tu estructura, podrías pasarla con el parámetro 'const'. Te quedaría algo así:

Código
  1. void desplegarValores(const struct persona *p)
  2. {
  3.    printf("Nombre: %s\n",p->nombre);
  4.    printf("Apellido paterno: %s\n",p->apellidoP);
  5.    printf("Apellido materno: %s\n",p->apellidoM);
  6.    printf("Rut: %s\n",p->rut);
  7.    printf("Edad: %i\n\n",p->edad);    
  8. }

Y en la función 'main' deberías llamarla así:

Código
  1. desplegarValores(&persona1);

Un saludo.


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: DarkSorcerer en 14 Enero 2014, 00:22 am
Gracias, me pudo funcionar :D


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: xiruko en 14 Enero 2014, 00:24 am
De nada :)

Saludos.


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: DarkSorcerer en 16 Enero 2014, 23:41 pm
Ahora tengo otra duda, error logico, el programa me compila pero no como lo esperaba.

Lo que hice fue ir mas allá de mi programa anterior, quise hacer un programa con menú incluido, se trata de una registradora de personas en un arreglo de structs, cada struct representa a una persona, pero cuando quiero desplegar por pantalla, sus datos aparecen como si no hubiera sido registrado, además otro error que tengo es que en una parte del programa cuando pregunta el nombre, se salta a la siguiente instrucción y no permite que se registre el nombre, en mi código lo verán, repetí 2 veces la línea de código problema. Otro problema menor es que no me funciona el comando "clrscr" para limpiar la pantalla,

Ahora, pondré mi código y al fondo del post coloqué un link para que puedan ver mi captura de lo que se ve en consola.

Código
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <windows.h>
  4.  
  5. struct persona personas[10];
  6. int cant = 0;
  7. bool flag = true;
  8.  
  9. struct persona{
  10.  
  11.    char nombre[30];
  12.    char apellidoP[30];
  13.    char apellidoM[30];
  14.    char rut[20];
  15.    int edad;    
  16.  
  17. };
  18.  
  19. void ingresarPersona(){
  20.  
  21.    printf("\n\nIngrese el nombre de la persona: ");
  22.    gets(personas[cant].nombre); //Aqui es el error.
  23.    gets(personas[cant].nombre);
  24.  
  25.    printf("\nIngrese el apellido paterno: ");
  26.    gets(personas[cant].apellidoP);
  27.  
  28.    printf("\nIngrese el apellido materno: ");
  29.    gets(personas[cant].apellidoM);
  30.  
  31.    printf("\nIngrese el RUT: ");
  32.    gets(personas[cant].rut);
  33.  
  34.    printf("\nIngrese la edad: ");
  35.    scanf("%i",&personas[cant].edad);    
  36.  
  37.    cant++;
  38.    printf("\n\nRegistro realizado exitosamente.\n");
  39.  
  40. }
  41.  
  42. void desplegarDatos(){
  43.  
  44.    printf("\n\nDesplegando datos personales de los registrados:\n");
  45.  
  46.    int i;
  47.  
  48.    for(i=0; i<cant; i++){
  49.  
  50.        printf("\n\nNombre: %s",personas[cant].nombre);
  51.        printf("\nApellido paterno: %s",personas[cant].apellidoP);
  52.        printf("\nApellido materno: %s",personas[cant].apellidoM);
  53.        printf("\nRut: %s",personas[cant].rut);
  54.        printf("\nEdad: %i\n",personas[cant].edad);      
  55.  
  56.    }
  57.  
  58. }
  59.  
  60. void menuPrincipal(){
  61.  
  62.    printf("\n::::: MENU PRINCIPAL :::::\n");
  63.    printf("\n1.- Ingresar nueva persona");
  64.    printf("\n2.- Informacion de personas inscritas");
  65.    printf("\n3.- Salir");
  66.    printf("\n\nDigite su opcion: ");
  67.  
  68.    int opcion;
  69.    scanf("%i",&opcion);
  70.  
  71.  
  72.    switch(opcion){
  73.  
  74.        case 1:
  75.  
  76.             ingresarPersona();
  77.  
  78.             break;
  79.  
  80.        case 2:
  81.  
  82.             desplegarDatos();
  83.  
  84.             break;
  85.  
  86.        case 3:
  87.  
  88.             flag = false;
  89.  
  90.             break;
  91.  
  92.    }    
  93.  
  94. }
  95.  
  96. int main(){
  97.  
  98.    while(flag){
  99.  
  100.        //clrscr();
  101.        menuPrincipal();
  102.  
  103.  
  104.    }
  105.  
  106.    system("PAUSE");
  107.    return 0;    
  108.  
  109. }
  110.  

http://www.subirimagenes.com/imagen-errorc-8777151.html


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: rir3760 en 17 Enero 2014, 02:01 am
Lo primero que debes hacer es cambiar colocar la declaración de la estructura antes de la declaración del array:
Código
  1. struct persona{
  2.  
  3.   char nombre[30];
  4.   char apellidoP[30];
  5.   char apellidoM[30];
  6.   char rut[20];
  7.   int edad;    
  8.  
  9. };
  10.  
  11. struct persona personas[10];

El porque se "salta" la lectura del nombre se debe a que estas intercalando llamadas a gets (no deberías, en su lugar fgets) y scanf, el tema se ha tratado en los foros y solo es cuestión de utilizar el motor de búsqueda.

Para solucionarlo debes eliminar el resto de la linea después de cada llamada a scanf (y antes de una llamada a fgets), por ejemplo la función "menuPrincipal" se debe cambiar a:
Código
  1. void menuPrincipal(void)
  2. {
  3.   int opcion;
  4.   int ch;
  5.  
  6.   puts("::::: MENU PRINCIPAL :::::");
  7.   puts("1.- Ingresar nueva persona");
  8.   puts("2.- Informacion de personas inscritas");
  9.   puts("3.- Salir");
  10.   puts("Digite su opcion: ");
  11.  
  12.   scanf("%i", &opcion);
  13.   /* Descartamos el resto de la linea */
  14.   while ((ch = getchar()) != EOF && ch != '\n')
  15.      ;
  16.  
  17.   switch(opcion){
  18.   case 1:
  19.      ingresarPersona();
  20.      break;
  21.   case 2:
  22.      desplegarDatos();
  23.      break;
  24.   case 3:
  25.      flag = false;
  26.      break;
  27.   }    
  28. }
El cambio en la función "ingresarPersona" es similar.

El porque no se imprimen los datos correctamente se debe al bucle de la función "desplegarDatos":
Código
  1. void desplegarDatos(void)
  2. {
  3.   int i;
  4.  
  5.   puts("Desplegando datos personales de los registrados:");
  6.   for(i = 0; i < cant; i++){
  7.      printf("\n\nNombre: %s",personas[cant].nombre);
  8.      printf("\nApellido paterno: %s",personas[cant].apellidoP);
  9.      printf("\nApellido materno: %s",personas[cant].apellidoM);
  10.      printf("\nRut: %s",personas[cant].rut);
  11.      printf("\nEdad: %i\n",personas[cant].edad);
  12.   }
  13. }
En el cuerpo de este utilizas "personas[ cant ]" cuando debería ser "personas[ i ]".

Un saludo


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: DarkSorcerer en 17 Enero 2014, 23:11 pm
Lo primero que debes hacer es cambiar colocar la declaración de la estructura antes de la declaración del array:
Código
  1. struct persona{
  2.  
  3.   char nombre[30];
  4.   char apellidoP[30];
  5.   char apellidoM[30];
  6.   char rut[20];
  7.   int edad;    
  8.  
  9. };
  10.  
  11. struct persona personas[10];

El porque se "salta" la lectura del nombre se debe a que estas intercalando llamadas a gets (no deberías, en su lugar fgets) y scanf, el tema se ha tratado en los foros y solo es cuestión de utilizar el motor de búsqueda.

Para solucionarlo debes eliminar el resto de la linea después de cada llamada a scanf (y antes de una llamada a fgets), por ejemplo la función "menuPrincipal" se debe cambiar a:
Código
  1. void menuPrincipal(void)
  2. {
  3.   int opcion;
  4.   int ch;
  5.  
  6.   puts("::::: MENU PRINCIPAL :::::");
  7.   puts("1.- Ingresar nueva persona");
  8.   puts("2.- Informacion de personas inscritas");
  9.   puts("3.- Salir");
  10.   puts("Digite su opcion: ");
  11.  
  12.   scanf("%i", &opcion);
  13.   /* Descartamos el resto de la linea */
  14.   while ((ch = getchar()) != EOF && ch != '\n')
  15.      ;
  16.  
  17.   switch(opcion){
  18.   case 1:
  19.      ingresarPersona();
  20.      break;
  21.   case 2:
  22.      desplegarDatos();
  23.      break;
  24.   case 3:
  25.      flag = false;
  26.      break;
  27.   }    
  28. }
El cambio en la función "ingresarPersona" es similar.

El porque no se imprimen los datos correctamente se debe al bucle de la función "desplegarDatos":
Código
  1. void desplegarDatos(void)
  2. {
  3.   int i;
  4.  
  5.   puts("Desplegando datos personales de los registrados:");
  6.   for(i = 0; i < cant; i++){
  7.      printf("\n\nNombre: %s",personas[cant].nombre);
  8.      printf("\nApellido paterno: %s",personas[cant].apellidoP);
  9.      printf("\nApellido materno: %s",personas[cant].apellidoM);
  10.      printf("\nRut: %s",personas[cant].rut);
  11.      printf("\nEdad: %i\n",personas[cant].edad);
  12.   }
  13. }
En el cuerpo de este utilizas "personas[ cant ]" cuando debería ser "personas[ i ]".

Un saludo

Ya me dí cuenta de mi error, y me equivoqué por una tontería T.T,  por esto "personas[cant]" en vez de "personas", es que andaba apurado y tenía que irme a otra parte :O, pero de todas maneras gracias por informarme.

Al final usé la siguiente instruccion "fflush(stdin)" para que no se saltara la lectura del nombre, ¿ que opinas ?


Título: Re: Necesito ayuda en "Structs" en C, tengo un error muy gordo
Publicado por: rir3760 en 18 Enero 2014, 01:41 am
No se recomienda utilizar fflush(stdin), las razones se describen en el tema |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).

Alternativas hay varias, puedes utilizar el motor de búsqueda para revisar los temas relacionados con el bufer de la entrada estándar.

Un saludo