elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Duda gets()
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Duda gets()  (Leído 2,296 veces)
apoeti

Desconectado Desconectado

Mensajes: 81



Ver Perfil
Duda gets()
« en: 9 Agosto 2012, 16:40 pm »

Estudiando el libro de "Aprenda C en 21 días" me ha surgido una duda en el día 14. El libro platea un programa que usa scanf() y gets() para limpiar el buffer de teclado.
Para plantear mi duda dejo el código fuente:
Código:
/* Limpieza de caracteres adicionales de stdin. */

#include <stdio.h>

void clear_kb(void);

main()
{
      int age;
      char name[20];
     
      /* Pide la edad del usuario. */
     
      puts("Enter your age.");
      scanf("%d", &age);
     
      /* Limpia a stdin de cualquier carácter adicional. */
     
      clear_kb();
     
      /* Pide ahora el nombre del usuario. */
     
      puts("Enter your first name.");
      scanf("%s", name);
      /* Display the data. */
     
      printf("Your age is %d.\n", age);
      printf("Your name is %s.\n", name);
}

void clear_kb(void)

/* Limpia a stdin de cualquier carácter que esté en espera. */
{
          char junk[80];
          gets(junk);
}

El código es muy sencillito y entiendo lo que hace, pero me surge una duda con la función clear_kb. La duda es que por qué si normalmente cuando se llama a gets(), esta función recoge carácteres hasta que encuentra un retorno de carro, en este caso la función no espera la entrada de carácteres. Entiendo que no lo haga cuándo limpia el buffer del teclado, pues para eso está, pero lo que no entiendo es: ¿Por qué la función no espera la entrada de carácteres cuando el buffer de teclado está limpio?

Espero respuestas. Espero haberme explicado en condiciones.
Gracias de antemano.


En línea

durasno


Desconectado Desconectado

Mensajes: 373


Ver Perfil
Re: Duda gets()
« Respuesta #1 en: 10 Agosto 2012, 05:36 am »

Citar
esta función recoge carácteres hasta que encuentra un retorno de carro
lee hasta encontrar un salto de linea

Citar
¿Por qué la función no espera la entrada de carácteres cuando el buffer de teclado está limpio?
no entiendo a q te referis. En el programa que pusiste siempre el bufer va a estar "sucio"(debido al caracter ENTER que deja scanf en el bufer del teclado), por lo tanto gets no espera la entrada de caracteres


Saludos


En línea

Ahorrate una pregunta, lee el man
xiruko


Desconectado Desconectado

Mensajes: 438


Ver Perfil
Re: Duda gets()
« Respuesta #2 en: 10 Agosto 2012, 06:36 am »

cuando usas scanf para leer un entero, esta funcion lee hasta el ultimo digito que encuentra y luego deja todo lo demas en el buffer de entrada. por ejemplo, si yo introdujera los siguientes caracteres cuando lo pidiera el scanf:

123fg45'\n' ('\n' ya que picas enter para introducir los datos y tambien se almacena en el bufer)

el scanf() leeria 123, y dejaria fg45'\n' en el buffer de entrada. esto es asi por propia definicion de la funcion scanf(). si quieres prueba este ejemplo y compruebalo por ti mismo:

Código
  1. #include <stdio.h>
  2. int main() {
  3. int a;
  4. char b[50];
  5. scanf("%d", &a);
  6.        //limpiarstdin();
  7. fgets(b, 49, stdin);
  8. printf("%d\n", a);
  9. printf("%s", b);
  10. return 0;
  11. }

sabiendo esto, puedes tambien comprobar que cuando usas gets(), esta lee en el bufer de entrada y ahi si que hay el caracter '\n', por lo que no te dara opcion a introducir nada y se recogera la basura que habia quedado en el bufer tras el scanf() hasta el caracter de nueva linea.

por cierto, esa funcion para eliminar la basura esta bien, aunque no limpiara del todo el bufer cuando haya una larga cola de basura (en tu caso, mayor a 80 caracteres). una alternativa es usar la siguiente funcion:

Código
  1. void limpiarstdin() {
  2. char a;
  3. while (a=getchar() != '\n');
  4. }

la cual si que limpiara del todo sea cual sea la longitud de basura.

un saludo!
En línea

apoeti

Desconectado Desconectado

Mensajes: 81



Ver Perfil
Re: Duda gets()
« Respuesta #3 en: 10 Agosto 2012, 16:23 pm »

Muchas gracias a los dos por las respuestas. Creo que me ha quedado claro, pero por si acaso, pregunto. Según lo que me habéis dicho, el scanf(), no recoge el '\n' y siempre lo deja en el teclado ¿Es eso cierto?
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Duda gets()
« Respuesta #4 en: 10 Agosto 2012, 18:27 pm »

En mi opinión un buen libro sobre C no debería tener ese tipo de ejemplos. No se recomienda el uso de la función "gets", la razón de ello se encuentra en uno de los temas fijos en el foro. Mismo caso con la función "scanf" cuando se utiliza en la forma:
Código
  1. char name[20];
  2.  
  3. /* ... */
  4.  
  5. puts("Enter your first name.");
  6. scanf("%s", name);
Ya que el riesgo es el mismo: no hay forma de limitar el numero de caracteres que se almacenan a partir de la dirección indicada.

Según lo que me habéis dicho, el scanf(), no recoge el '\n' y siempre lo deja en el teclado ¿Es eso cierto?
Usualmente si.

Una respuesta mejor es: depende del especificador de formato (por ejemplo "%d", "%s", etc.) utilizado.

Con todos ellos (salvo "%c" y "%[]") lo primero que hace la función es descartar el espacio blanco (espacio, tabulador, etc.). A continuación la función consume todos los caracteres que cumplan con el especificador (como ya te comento xiruko ), eso continua hasta cumplir con lo indicado o se encuentre un carácter invalido (el cual se queda en el bufer de la entrada estándar).

Un ejemplo de esto ultimo, una forma mas segura es:
Código
  1. char name[20];
  2.  
  3. /* ... */
  4.  
  5. puts("Enter your first name.");
  6. scanf("%19s", name);
Así la función descarta el espacio blanco, lee y almacena los caracteres (una palabra) en el array (máximo 19). Por ultimo almacena el '\0'.

Un saludo
En línea

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
apoeti

Desconectado Desconectado

Mensajes: 81



Ver Perfil
Re: Duda gets()
« Respuesta #5 en: 11 Agosto 2012, 14:25 pm »

Muchas gracias, ya me ha quedado claro.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Pequeña duda con un comando batch (NUEVA DUDA RELACIONADA)
Scripting
revenge1252 9 9,767 Último mensaje 13 Febrero 2008, 21:41 pm
por revenge1252
Duda duda y duda de Metasploit
Bugs y Exploits
huber_nomas 4 5,797 Último mensaje 17 Febrero 2012, 14:00 pm
por MauroMasciar
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines