/
Inicio :: Foros

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

Porque evitar el uso de la función "gets"

 
      Índice del Foro elrincondelc.com -> FAQ de C
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
rir3760



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

MensajePublicado: 26/07/2012 3:18 pm
Título: Porque evitar el uso de la función "gets"

Se debe evitar el uso de la función "gets" porque es la única realmente peligrosa en la biblioteca estándar de C. Dado un programa como este:
Código:
#include <stdio.h>
#include <stdlib.h>

#define NUM_CHARS  80

int main(void)
{
   char nombre[NUM_CHARS];
   
   printf("Indica tu nombre: ");
   fflush(stdout);
   if (gets(nombre) == NULL)
      return EXIT_FAILURE;
     
   printf("Hola %s!\n", nombre);
   
   return EXIT_SUCCESS;
}

La función "gets" al ejecutarse la llamada:
Código:
gets(nombre)

Tomara de la entrada estándar todos los caracteres que componen una linea de texto sin importar su numero y tratara de almacenarlos a partir de la dirección indicada. Si se sobrepasa la capacidad del contenedor ello resulta en comportamiento no definido (cualquier cosa puede pasar, por ejemplo en MS Windows el usual mensaje de error indicando que la aplicación debe cerrarse).

----

La solución es remplazar el uso de "gets" por fgets, esta ultima tiene la ventaja de aceptar, como segundo argumento, el numero máximo de caracteres a almacenar. El programa anterior corregido:
Código:
#include <stdio.h>
#include <stdlib.h>

#define NUM_CHARS  80

int main(void)
{
   char nombre[NUM_CHARS];
   
   printf("Indica tu nombre: ");
   fflush(stdout);
   if (fgets(nombre, NUM_CHARS, stdin) == NULL)
      return EXIT_FAILURE;

   printf("Hola %s!\n", nombre);
   
   return EXIT_SUCCESS;
}

La función "fgets" recibe tres argumentos: el primero es la dirección en memoria donde se almacenaran los caracteres, el segundo el numero de estos (incluyendo el '\n' y el '\0') y el tercero de donde se tomaran ("stdin" es la entrada estándar).

----

Una diferencia importante entre "gets" y "fgets" es que esta ultima no descarta el carácter de avance de linea (el '\n'), este se almacena como parte de la cadena. Para obtener un comportamiento idéntico debemos descartar ese carácter para lo cual hay varias opciones:

A) Mediante un bucle encontramos el '\0' en la cadena, verificamos el carácter anterior y lo eliminamos si es el avance de linea.

B) Utilizando la función "strlen" (prototipo en <string.h>) obtenemos la longitud de la cadena, verificamos el carácter anterior y lo eliminamos si es el avance de linea.

C) Buscamos directamente el avance de linea mediante la función "strchr" (prototipo en <string.h>), si este existe lo eliminamos sustituyéndolo con un '\0'.

Un programa de ejemplo utilizando la primera aproximación:
Código:
#include <stdio.h>
#include <stdlib.h>

#define NUM_CHARS  80

char *usr_fgets(char *cad, int num_chars, FILE *entrada);

int main(void)
{
   char nombre[NUM_CHARS];
   
   printf("Indica tu nombre: ");
   fflush(stdout);
   if (usr_fgets(nombre, NUM_CHARS, stdin) == NULL)
      return EXIT_FAILURE;
   
   printf("Hola %s!\n", nombre);
   
   return EXIT_SUCCESS;
}

char *usr_fgets(char *cad, int num_chars, FILE *entrada)
{
   int i;
   
   if (fgets(cad, num_chars, entrada) == NULL)
      return NULL;
   
   /* Buscamos y eliminamos (si existe) el caracter '\n' */
   for (i = 0; cad[i] != '\0'; i++)
      ;
   if (i > 0 && cad[i - 1] == '\n')
      cad[i - 1] = '\0';
   
   return cad;
}

_________________
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Volver arriba
Anastacius



Registrado: 26 Oct 2013
Mensajes: 41

MensajePublicado: 30/10/2013 8:37 am
Título: Gracias

No se si se puede comentar aqui, si no se puede, pido cierren el mensaje mio...

Agradezco mucho esto, yo estaba teniendo un error por dicha funcion, el cual corregi simplemente agrandando el arreglo, pero es mejor cambiar a fgets de ahora en adelante...

Muchas gracias por tu servicio fiel en esta comunidad
_________________
Programacion en C - HTML - Batch -
Aprendiendo : Java...
Volver arriba
      Índice del Foro elrincondelc.com -> FAQ de C
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