/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

fgets y estructura

 
      Índice del Foro elrincondelc.com -> C/C++ en General
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
K1LL3RDO6



Registrado: 03 Abr 2005
Mensajes: 3

MensajePublicado: 03/11/2007 8:13 pm
Título: fgets y estructura

Hola, soy nuevo en esto de la programación y tengo una duda.

Estoy tratando de usar la función fgets para recibir un string, mi problema es que al ejecutar el programa, se salta la lectura del string.

Esto solo me pasa si pongo las variables dentro de una estructura, pues si no lo hago no hay problemas.

Tengo que hacerlo asi por que nos estan enseñando eso ahora.

Esto lo estoy compilando en linux.

Código:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <conio.h>


void menu();
void ingresar();
void imprimir();
void mayor18();
void buscar_nombre();


struct registro {

    char nombre[20], apellido[20];
    int edad;
    char domicilio[25];

};


struct registro reg;
FILE *a;
char ok;



int main()
{

//    clrscr();
//    ingresar();
//    imprimir();
//    mayor18();
//    buscar_nombre();
    menu();
    return 0;
}


void menu()
{

   short opcion;


   do {

       system("clear");
       printf("MENU\n\n");
       printf("1. Ingresar datos\n");
       printf("2. Imprimir registros\n");
       printf("3. Mayores de 18\n");
       printf("4. Buscar por nombre\n");
       printf("0. Salir\n");
   
       printf("Ingresa opcion: ");
       scanf("%d", &opcion);

       switch (opcion) {


           case 0:
               break;

           case 1:
               ingresar();
          break;

           case 2:
               imprimir();
          break;

           case 3:
               mayor18();
          break;

           case 4:
               buscar_nombre();
          break;

           default:
               printf("Opcion no valida\n");
          break;

       }

   } while ( opcion != 0);
}


void ingresar()
{

    a = fopen("datos.dat", "w");

    if (a == NULL) {

   printf("No se puede crear\n");
//   getch();
    }
    else {

   do {

//       clrscr();
       printf("\nIngreso datos\n");
       printf("Nombre: ");
       scanf("%s", ®.nombre);
       printf("Apellido: ");
       scanf("%s", ®.apellido);
       printf("Edad: ");
       scanf("%d", ®.edad);
       printf("Domicilio: ");
       fgets(reg.domicilio, 25, a);
       //scanf("%s", ®.domicilio);
       //getline(reg.domicilio, 25); /* toma los espacios tb*/
       fwrite(®, sizeof(reg), 1, a);
       printf("Registro grabado.. Ingresa otro s/n: ");
       scanf("%s", &ok);

   } while (ok=='s');
    }
    fclose(a);
}


void imprimir()
{

    a = fopen("datos.dat", "r");

    if (a == NULL) {

   printf("\nError al abrir el archivo");
//   getch();
    }
    else {

   do {

       fread(®, sizeof(reg), 1, a);
       if (feof(a)) {
      printf("fin de lectura...\n\n");
//      getch();
       }
       else {

      printf("\n\nNombre: %s\n", reg.nombre);
      printf("Apellido: %s\n", reg.apellido);
      printf("Edad: %d\n", reg.edad);
      printf("Domicilio: %s\n", reg.domicilio);
       }
   } while (!feof(a));
    }

    fclose(a);
    system("sleep 10");    /* realiza un sleep de 10 seg */

}


void mayor18()
{

    short cont = 0;

/* Abre el archivo */
//    a = fopen("datos.dat", "r");

//    if (a == NULL) {

      if ( (a = fopen("datos.dat", "r") ) == NULL ) {

   printf("Error a abrir archivo\n");
//   getch();
    }
    else {

   do {

       fread(®, sizeof(reg), 1, a);

       if ( feof(a)) {

      printf("fin de lectura\n");
       }
       else {

      if (reg.edad > 18) {

                    if (cont == 0)

              printf("PERSONAS MAYORES de 18\n\n");

          printf("Nombre: %s\n", reg.nombre);
          printf("Apellido: %s\n", reg.apellido);
          printf("Edad: %d\n", reg.edad);
          printf("Domicilio: %s\n\n", reg.domicilio);
          cont = 1;
      }
       }
   } while (!feof(a));
    }

    fclose(a);
//    getch();
}


void buscar_nombre()
{

   char nombre[20];
   short aux = 0;

   printf("BUSQUEDA PERSONA POR NOMBRE\n\n");
   printf("Nombre: ");
   scanf("%s", &nombre);

   if ( (a = fopen("datos.dat", "r") ) == NULL ) {

       printf("Error a abrir archivo\n");
      
   }
   else {

       do {

           fread(®, sizeof(reg), 1, a);

           if ( feof(a))

               printf("fin de lectura\n");
      

      else {
      
          if ( strcmp(nombre, reg.nombre) == 0) {

              if ( aux == 0)

                       printf("Se encontro a:\n\n");


         printf("Nombre: %s %s\n", reg.nombre, reg.apellido);
         printf("Edad: %d\n", reg.edad);
         printf("Domicilio: %s\n", reg.domicilio);
         aux = 1;
            
               }
         
      }

       } while (!feof(a));
   }

   fclose(a);
}




Al ejecutarse se ve asi


Código:

MENU

1. Ingresar datos
2. Imprimir registros
3. Mayores de 18
4. Buscar por nombre
0. Salir
Ingresa opcion: 1

Ingreso datos
Nombre: juan
Apellido: perez
Edad: 30
Domicilio: Registro grabado.. Ingresa otro s/n:


Como se puede ver, después de "Domicilio" me dice inmediatamente que el registro está grabado, y no me permite ingresar el domicilio de la persona.

Agradeceria si alguien me puede ayudar, darme alguna pista de por qué está mal por favor.
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3676
Ubicación: Mexico

MensajePublicado: 04/11/2007 6:26 am
Título:

El error es uno muy comun causado por el uso intercalado de la funcion scanf con otras funciones como gets/fgets/etc.

En esta parte de tu programa:
Código:
printf("Edad: ");
scanf("%d", ®.edad);

printf("Domicilio: ");
fgets(reg.domicilio, 25, a);

La funcion scanf lee el numero de la entrada estandar pero no procesa el espacio blanco despues de este (incluyendo el avance de linea o '\n').

Supongamos que al presentarse la peticion de la edad se teclea "123" seguido de {ENTER}, en este caso el bufer de la entrada estandar contiene:
1, 2, 3, {ENTER}
Los tres primeros caracteres son procesados por scanf para formar el numero 123 pero (este es el gran problema) el avance de linea se queda en el bufer.

La siguiente funcion (fgets) trata de leer una linea y se encuentra con el remanente de scanf:
{ENTER}
Ese avance de linea fgets lo toma como una linea en blanco y es la causa de que el programa no te permita introducir el domicilio.

Para evitar todo esto basta con eliminar los caracteres restantes de la linea despues de la llamada a scanf:
Código:
printf("Edad: ");
scanf("%d", ®.edad);
/* eliminar resto de la linea*/
{
int ch;

while ((ch = getchar()) != EOF && ch != '\n')
   ;
}

printf("Domicilio: ");
fgets(reg.domicilio, 25, a);


Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
K1LL3RDO6



Registrado: 03 Abr 2005
Mensajes: 3

MensajePublicado: 04/11/2007 5:13 pm
Título:

rir3760 escribió:
El error es uno muy comun causado por el uso intercalado de la funcion scanf con otras funciones como gets/fgets/etc.

En esta parte de tu programa:
Código:
printf("Edad: ");
scanf("%d", ®.edad);

printf("Domicilio: ");
fgets(reg.domicilio, 25, a);

La funcion scanf lee el numero de la entrada estandar pero no procesa el espacio blanco despues de este (incluyendo el avance de linea o '\n').

Supongamos que al presentarse la peticion de la edad se teclea "123" seguido de {ENTER}, en este caso el bufer de la entrada estandar contiene:
1, 2, 3, {ENTER}
Los tres primeros caracteres son procesados por scanf para formar el numero 123 pero (este es el gran problema) el avance de linea se queda en el bufer.

La siguiente funcion (fgets) trata de leer una linea y se encuentra con el remanente de scanf:
{ENTER}
Ese avance de linea fgets lo toma como una linea en blanco y es la causa de que el programa no te permita introducir el domicilio.

Para evitar todo esto basta con eliminar los caracteres restantes de la linea despues de la llamada a scanf:
Código:
printf("Edad: ");
scanf("%d", ®.edad);
/* eliminar resto de la linea*/
{
int ch;

while ((ch = getchar()) != EOF && ch != '\n')
   ;
}

printf("Domicilio: ");
fgets(reg.domicilio, 25, a);


Un saludo




Hola, escribi lo que pusiste, pero tampoco me permite poder ingresar la dirección, compilo, ejecuto y se salta tambien poder ingresar el domicilio.

saludos
Volver arriba
daltomi



Registrado: 28 Abr 2007
Mensajes: 117
Ubicación: Argentina

MensajePublicado: 04/11/2007 6:40 pm
Título:

Hola.
En la función ingresar existe un error:
Creas un archivo de sólo escritura y luego utilizas la función fgets para leer el archivo, es decir, debes reemplazar fgets por scanf,o mejor dicho, comenta fgets y quita el formato de comentario al scanf que ya existe.

Saludos.
Volver arriba
Diabliyo



Registrado: 14 Abr 2004
Mensajes: 316
Ubicación: En la Luna

MensajePublicado: 04/11/2007 7:38 pm
Título:

Limpia el buffer...

Código:
//para windows.
fflush(stdin);

//para linux
while( getch()!='\n' );

_________________

Volver arriba
mamntc02



Registrado: 30 Abr 2007
Mensajes: 248

MensajePublicado: 05/11/2007 4:38 am
Título:

Hola,

Volvemos a un error recurrente.
Código:
fflush(stdin)
no tiene por qué funcionar (ni en Linux, ni en Windows ni en ninguna plataforma). No hay ninguna función en el standard q vacie los buffer de entrada, fflush sólo funciona (o sólo es obligatorio q funcione) para buffers de salida. Puede q el compilador igualmente implemente la función para los buffers de entrada, pero nadie le obliga y lo más probable es q no te funcione. La solución es la q comenta rir3760

Saludos.
Volver arriba
K1LL3RDO6



Registrado: 03 Abr 2005
Mensajes: 3

MensajePublicado: 05/11/2007 9:11 am
Título:

Hice lo que me dijeron, estoy probando en windows y no me resulta, aca le saque un screenshot al turbo c, ejecutando el programita.



No me funciona en windows o linux, no se si falto algo =\

Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>


void menu();
void ingresar();
void imprimir();
void mayor18();
void buscar_nombre();


struct registro {

    char nombre[20], apellido[20];
    int edad;
    char domicilio[25];

};


struct registro reg;
FILE *a;
char ok;



int main()
{


    menu();
    return 0;
}


void menu()
{

   short opcion;


   do {

       clrscr();
       printf("MENU\n\n");
       printf("1. Ingresar datos\n");
       printf("2. Imprimir registros\n");
       printf("3. Mayores de 18\n");
       printf("4. Buscar por nombre\n");
       printf("0. Salir\n\n");
   
       printf("Ingresa opcion: ");
       scanf("%d", &opcion);

       switch (opcion) {


           case 0:
               break;

           case 1:
               ingresar();
          break;

           case 2:
               imprimir();
          break;

           case 3:
               mayor18();
          break;

           case 4:
               buscar_nombre();
          break;

           default:
               printf("Opcion no valida\n");
          break;

       }

   } while ( opcion != 0);
}


void ingresar()
{

    a = fopen("datos.dat", "w");

    if (a == NULL) {

   printf("No se puede crear\n");
    }
    else {

   do {

       printf("\nIngreso datos\n");
       printf("Nombre: ");
       scanf("%s", ®.nombre);
       printf("Apellido: ");
       scanf("%s", ®.apellido);
       printf("Edad: ");
       scanf("%d", ®.edad);
       /* eliminar resto de la linea */
       {

       int ch;

       while ((ch = getchar()) != EOF && ch  != '\n')
          ;

       }
       printf("Domicilio: ");
       fgets(reg.domicilio, 25, a);
       //scanf("%s", ®.domicilio);
       //cin.getline(reg.domicilio, 25); /* toma los espacios tb*/
       fwrite(®, sizeof(reg), 1, a);
       printf("Registro grabado.. Ingresa otro s/n: ");
       scanf("%s", &ok);

   } while (ok=='s');
    }
    fclose(a);
    getch();
}


void imprimir()
{

    a = fopen("datos.dat", "r");

    if (a == NULL) {

   printf("\nError al abrir el archivo");

    }
    else {

   do {

       fread(®, sizeof(reg), 1, a);
       if (feof(a)) {
      printf("fin de lectura...\n\n");

       }
       else {

      printf("\n\nNombre: %s\n", reg.nombre);
      printf("Apellido: %s\n", reg.apellido);
      printf("Edad: %d\n", reg.edad);
      printf("Domicilio: %s\n", reg.domicilio);

       }
   } while (!feof(a));
    }

    fclose(a);
//    system("sleep 10");    /* realiza un sleep de 10 seg */
    getch();

}


void mayor18()
{

    short cont = 0;


      if ( (a = fopen("datos.dat", "r") ) == NULL ) {

   printf("Error a abrir archivo\n");

    }
    else {

   do {

       fread(®, sizeof(reg), 1, a);

       if ( feof(a)) {

      printf("fin de lectura\n");
       }
       else {

      if (reg.edad > 18) {

                    if (cont == 0)

              printf("PERSONAS MAYORES de 18\n\n");

          printf("Nombre: %s\n", reg.nombre);
          printf("Apellido: %s\n", reg.apellido);
          printf("Edad: %d\n", reg.edad);
          printf("Domicilio: %s\n\n", reg.domicilio);
          cont = 1;
      }
       }
   } while (!feof(a));
    }

    fclose(a);
    getch();
}


void buscar_nombre()
{

   char nombre[20];
   short aux = 0;

   printf("BUSQUEDA PERSONA POR NOMBRE\n\n");
   printf("Nombre: ");
   scanf("%s", &nombre);

   if ( (a = fopen("datos.dat", "r") ) == NULL ) {

       printf("Error a abrir archivo\n");
      
   }
   else {

       do {

           fread(®, sizeof(reg), 1, a);

           if ( feof(a))

               printf("fin de lectura\n");
      

      else {
      
          if ( strcmp(nombre, reg.nombre) == 0) {

              if ( aux == 0)

                       printf("Se encontro a:\n\n");


         printf("Nombre: %s %s\n", reg.nombre, reg.apellido);
         printf("Edad: %d\n", reg.edad);
         printf("Domicilio: %s\n", reg.domicilio);
         aux = 1;
            
               }
         
      }

       } while (!feof(a));
   }

   fclose(a);
   getch();
}



La idea es que me pueda tomar un domicilio el cual puede llevar un espacio en blanco (Ejemplo "juan claro"), pues hay calles que llevan espacios en blanco.
Poniendo cin.getline para almacenar el domicilio con espacio blanco, con su #include <iostream> respectivo, funciona lo que quiero realizar, pero entiendo que esa función es de c++ y me gustaría que sólo fuera con c.

muchas gracias por las respuestas.
Volver arriba
      Índice del Foro elrincondelc.com -> C/C++ en General
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com