Foros del Web » Programación para mayores de 30 ;) » C/C++ »

fgets me guarda una línea innecesaria

Estas en el tema de fgets me guarda una línea innecesaria en el foro de C/C++ en Foros del Web. Estoy practicando un poco de fgets con cadenas y me he encontrado con algo bastante extraño, que consiste en que las cadenas que yo entrego ...
  #1 (permalink)  
Antiguo 10/06/2011, 09:15
 
Fecha de Ingreso: mayo-2011
Mensajes: 26
Antigüedad: 12 años, 11 meses
Puntos: 1
fgets me guarda una línea innecesaria

Estoy practicando un poco de fgets con cadenas y me he encontrado con algo bastante extraño, que consiste en que las cadenas que yo entrego de entrada, me salen correctas, pero me salen con una línea de más.

Les explico con código en mano. Esta aplicación pretende guardar en una estructura temporal cuatro datos
1) El nombre de un DVD
2) El género de un DVD
3) El número de discos de un DVD
4) La duración total del DVD en minutos

Código C:
Ver original
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4.  
  5. struct dvd {
  6.  char name[255];
  7.  char genero[50];
  8.  int discs_number;
  9.  int length;
  10. };
  11.  
  12. int main()
  13. {
  14.     struct dvd temporal;
  15.  
  16.     char discs_number[2];
  17.     char length[4];
  18.  
  19.     printf("Nombre del DVD\n");
  20.              fgets(temporal.name, 255, stdin);
  21.  
  22.     printf("%s\n", temporal.name);
  23.  
  24.     printf("Género del DVD\n");
  25.             fgets(temporal.genero, 50, stdin);
  26.  
  27.     printf("%s\n", temporal.genero);
  28.  
  29.     printf("Número de discos del DVD\n");
  30.              fgets(discs_number, 2, stdin);
  31.  
  32.     temporal.discs_number = atoi(discs_number);
  33.  
  34.     printf("%d\n", temporal.discs_number);
  35.  
  36.     printf("Duración del DVD\n");
  37.        
  38.     while(getchar() != '\n');
  39.             fgets(length, 4, stdin);
  40.  
  41.     temporal.length = atoi(length);
  42.    
  43.     printf("%d\n", temporal.length);
  44.  
  45.    
  46.  
  47.     return(0);
  48. }

Cuando ejecuto el programa, si introducen el nombre del DVD, la cadena que se me regresa es correcta cuando yo haga el printf, pero automáticamente se me salta una línea. Lo mismo pasa con el género del DVD.

Los campos de número de discos y de duración del DVD funcionan correctamente.

Pruébenlo con estos datos:
Nombre: Batman
Género: Acción
Número de discos: 1
Duración; 126

¿Que puede estar pasando? (por cierto, mi código está compilado con GCC)

Saludos!
  #2 (permalink)  
Antiguo 10/06/2011, 09:55
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: fgets me guarda una línea innecesaria

Tu problema esta que el fgets deja almacenado el caracter de salto de linea (\n)
Lo que tienes que hacer es en los dos primeros printf sacar el \n que haces que bajes dos lineas.

En los otros dos no sucede porque imprimes enteros...y el caracter de fin de linea se pierda cuando lo combiertes a entero.
  #3 (permalink)  
Antiguo 10/06/2011, 10:49
 
Fecha de Ingreso: mayo-2011
Mensajes: 26
Antigüedad: 12 años, 11 meses
Puntos: 1
Respuesta: fgets me guarda una línea innecesaria

Me funcionó bien.

Ahora, me queda una duda. A raíz de lo que hice, concluyo que el fgets no me servirá si lo que quiero es poner en una lista todos los datos de tal forma que me queden así (tomando el ejemplo):

Batman Acción 1 126

¿Se puede hacer algo para que queden los datos así?

Saludos!
  #4 (permalink)  
Antiguo 10/06/2011, 12:03
Avatar de CapacProg  
Fecha de Ingreso: marzo-2010
Ubicación: Lima - Perú
Mensajes: 324
Antigüedad: 14 años
Puntos: 71
Respuesta: fgets me guarda una línea innecesaria

Utiliza debajo de cada fgets, fflush(stdin), para liberar el buffer que almacena '\n' y que te esta causando ese problema.
__________________
%
El mejor guerrero no es el que triunfa siempre sino el que vuelve sin miedo a la batalla.
%
  #5 (permalink)  
Antiguo 10/06/2011, 13:35
 
Fecha de Ingreso: mayo-2011
Mensajes: 26
Antigüedad: 12 años, 11 meses
Puntos: 1
Respuesta: fgets me guarda una línea innecesaria

Cita:
Iniciado por CapacProg Ver Mensaje
Utiliza debajo de cada fgets, fflush(stdin), para liberar el buffer que almacena '\n' y que te esta causando ese problema.
Para lo que estoy buscando ahora, que es poner todos los datos en una sola línea, lo hice y no me resulta.

Ahora si es respecto de lo anterior ya lo solucioné.

Saludos!
  #6 (permalink)  
Antiguo 10/06/2011, 19:01
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: fgets me guarda una línea innecesaria

fflush(stdin) no sirva aca si se esta leyendo desde un archivo y no desde el stdin...ademas la lectura del fgets viene con el \n....no es problema de que quede en el buffer.

Ahora segun tu problema nuevo, el nombre del DVD puede tener spacios o siempre es una sola palabra??

Si es una sola palaabra puedes usar fscanf. Que lee desde una entrada formateada. Directamente te dara la conversion a entero tambien.
  #7 (permalink)  
Antiguo 11/06/2011, 05:44
 
Fecha de Ingreso: mayo-2011
Mensajes: 26
Antigüedad: 12 años, 11 meses
Puntos: 1
Respuesta: fgets me guarda una línea innecesaria

Cita:
Iniciado por sam90 Ver Mensaje
Ahora segun tu problema nuevo, el nombre del DVD puede tener spacios o siempre es una sola palabra??
Puede tener espacios (la gracia es que pueda guardar por ejemplo "Pollitos en Fuga" o "Mi Villano Favorito").

Saludos!
  #8 (permalink)  
Antiguo 11/06/2011, 10:53
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: fgets me guarda una línea innecesaria

En ese caso debes tener algun delimitador porque se va a confundir con el genero..Es posible pero hay que hacer una lectura mas detallada...por ejemplo leer hasta un caracter especial o una cantidad fija de caracteres para el nombre.
Depende como lo quieras hacer.
  #9 (permalink)  
Antiguo 12/06/2011, 06:08
 
Fecha de Ingreso: mayo-2011
Mensajes: 26
Antigüedad: 12 años, 11 meses
Puntos: 1
Respuesta: fgets me guarda una línea innecesaria

Les cuento que ya solucioné mi problema, lo que necesitaba era algo que pudiera sacarme el salto de línea del fgets, para eso en otro foro consulté y me dijeron que usara la función strchr, para poder reemplazar el caracter de salto de línea con el carácter de fin de cadena.

El programa quedaría así:
Código C:
Ver original
  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4.  
  5. struct dvd {
  6.     char name[255];
  7.     char genero[50];
  8.     int discs_number;
  9.     int length;
  10. };
  11.  
  12. int main()
  13. {
  14.     struct dvd temporal;
  15.     char discs_number[2];
  16.     char length[4];
  17.     char *pch;
  18.  
  19.     printf("Nombre del DVD\n");
  20.     fgets(temporal.name, 255, stdin);
  21.     // Buscas la posicion del caracter nueva linea (10) en la cadena
  22.     pch = strchr(temporal.name, 10);
  23.     // Si la encontro, reemplazas nueva linea con nulo, que es el fin
  24.     // de cadena ('\0')
  25.     if (pch != NULL)
  26.     {
  27.         *pch = '\0';
  28.     }
  29.  
  30.     printf("%s\n", temporal.name);
  31.  
  32.     printf("Género del DVD\n");
  33.     fgets(temporal.genero, 50, stdin);
  34.     pch = strchr(temporal.genero, 10);
  35.     if (pch != NULL)
  36.     {
  37.         *pch = '\0';
  38.     }
  39.  
  40.     printf("%s\n", temporal.genero);
  41.  
  42.     printf("Número de discos del DVD\n");
  43.     fgets(discs_number, 2, stdin);
  44.  
  45.     temporal.discs_number = atoi(discs_number);
  46.  
  47.     printf("%d\n", temporal.discs_number);
  48.  
  49.     printf("Duración del DVD\n");
  50.  
  51.     while(getchar() != '\n');
  52.     fgets(length, 4, stdin);
  53.  
  54.     temporal.length = atoi(length);
  55.  
  56.     printf("%d\n", temporal.length);
  57.  
  58.     printf("%s %s %d %d", temporal.name, temporal.genero, temporal.discs_number, temporal.length);
  59.     return(0);
  60. }

De todas maneras igual se agradece la ayuda =)

Saludos!
  #10 (permalink)  
Antiguo 12/06/2011, 11:55
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: fgets me guarda una línea innecesaria

Yo pense que querias guardar en el archivo todo en una linea...

Etiquetas: fgets
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:51.