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

 

 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  el porque del scanf no es recomendable
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: el porque del scanf no es recomendable  (Leído 4,300 veces)
nicolasblues86

Desconectado Desconectado

Mensajes: 38



Ver Perfil
el porque del scanf no es recomendable
« en: 16 Mayo 2010, 20:53 pm »

Hola Gente!!

BUENO ESTO ES UNA EXPLICACIÓN DE PORQUE AVECES EL SCANF SE COMPORTA DE MANERA EXTRAÑA. ESPERO QUE SE ENTIENDA,  

voy explico porque el uso de scanf no es recomendable..
para empezar es un error decir que un programa lee del teclado en verdad lo que hace es leer de un area de memoria llamado "buffer de teclado" (no siempre es así, esto se puede manipular mediante la función  setvbuf y el modo _IOFBF, que especifica que lea hasta que el buffer esté lleno.) y el buffer del teclado es "buffer de linea" esto quiere decir que los datos que provienen del teclado se insertan linea por linea y no caracter a caracter . Es por eso que cuando leemos de ahí, por más que ingresemos muchos caracteres, hasta que no ingresamos el fin de línea (enter) el programa no lee nada y se queda trabado esperando que haya algo en el buffer.

si el buffer no está vacío, sí o sí hay al menos un fin de línea;
el buffer siempre tiene un carácter de fin de línea al final.

El gran problema con scanf es que no siempre leerá el fin de linea lo que nos lleva a que el buffer quede con basura, osea con caracteres no leídos los cuales la próxima vez que invoquemos a scanf los leerá e intentara limpiar el buffer ocasionando un salto de linea e impediendonos ingresar el dato requerido.  de mas esta decir que esto podría causar algunos problemas al programador.
scanf solo lee hasta que encuentre el formato que le especificamos, esto conlleva a otro gran problema ya que si nosotros le decimos que lea un entero (%i") y se le ingresan 2 enteros separados por un espacio scanf solo leerá hasta encontrar el formato especificado dejando al buffer sucio con ese entero de mas.
Otro problema que tenemos es que no hace casi ningún tipo de chequeo a la hora de verificar los datos ingresados si se le indica que se ingresara un entero y el usuario ingresa una letra esté hace una conversión a entero lo cual genera un problema.


en el siguiente segmento de programa intenten lo siguiente cuando les piede ingresar los datos pongan algo así como "50 10" (sin las comillas) y veran como el buffer quedara  sucio  con con el entero 10 entonces cuando se llama de nuevo a scanf "asimila" que 10 es lo que se ingreso y por eso no nos deja ingresar el dato e imprime el nuevo valor de i       

Código
  1.  
  2. nt main(int argc, char** argv)
  3. {
  4. int i;
  5.  
  6. scanf ("%d", &i );
  7. printf ("%d\n",i);
  8. scanf ("%d", &i );
  9. printf ("%d",i);
  10.  
  11.  
  12. return 0;
  13.  
  14.  
  15. }
  16.  
  17.  



por estas razones no es recomendable usarlo siempre se puede suplantar con algo que no ensucie el buffer para eso utilsaremos sscanf y fgets :

 
Código
  1.  
  2. #include <stdio.h>
  3.  
  4.  
  5.  
  6. int main()
  7. {
  8.   char nombre[20]="", entrada[81]="";
  9.   unsigned int edad=0;
  10.  
  11.   printf( "Escriba su nombre y edad, separados por un espacio:\n" );
  12.   fgets(entrada, 20, stdin ); //llenamos el buffer reservando 20 caracteres y stdin es la entrada standar
  13.   sscanf( entrada, "%s %u", nombre, &edad ); //con sscanf introducimos lo que tenemos en el buffer tanto en nombre como en edad    
  14.  
  15.   printf( "Has escrito: %s\n", entrada ); //lo que tenemos en el buffer
  16.   printf( "Nombre: %s. Edad: %d\n", nombre, edad ); //
  17.  
  18.  
 

El uso de fgets puede traer inconvenientes menores los cuales son  solucionables no voy a profundizar en este tema ya que ya hay un pequeño post que habla del mismo

bueno eso es todo...

Saludos Cordiales


« Última modificación: 16 Mayo 2010, 21:20 pm por nicolasblues86 » En línea

Solamente hay 10 clases de personas en el mundo los que saben leer binario y los que no
Og.


Desconectado Desconectado

Mensajes: 822


Aprendiendo de la vida


Ver Perfil
Re: el porque del scanf no es recomendable
« Respuesta #1 en: 16 Mayo 2010, 21:00 pm »

Solo para agregar algo, para limpiar el buffer pueden hacer:

Código
  1. fseek(stdin, 0, SEEK_END);

Saludos!


En línea

|-
Akai


Desconectado Desconectado

Mensajes: 823



Ver Perfil
Re: el porque del scanf no es recomendable
« Respuesta #2 en: 16 Mayo 2010, 21:26 pm »

Solo para agregar algo, para limpiar el buffer pueden hacer:

Código
  1. fseek(stdin, 0, SEEK_END);

Saludos!


o
Código
  1. setbuf(stdin,NULL);

EDIT: corregida la sentencia "setbuf", sobraba una f. Gracias Leo Gutiérrez.
« Última modificación: 16 Mayo 2010, 21:44 pm por Akai » En línea

leogtz
. . .. ... ..... ........ ............. .....................
Colaborador
***
Desconectado Desconectado

Mensajes: 3.069


/^$/


Ver Perfil WWW
Re: el porque del scanf no es recomendable
« Respuesta #3 en: 16 Mayo 2010, 21:30 pm »

Solo para agregar algo, para limpiar el buffer pueden hacer:

Código
  1. fseek(stdin, 0, SEEK_END);

Saludos!


o
Código
  1. setbuff(stdin,NULL);

Es setbuf(), no setbuff().

Gracias por el dato.

¿Alguno sabe su equivalente en C++ o tendríamos que usar lo mismo?
« Última modificación: 16 Mayo 2010, 21:33 pm por Leo Gutiérrez. » En línea

Código
  1. (( 1 / 0 )) &> /dev/null || {
  2. echo -e "stderrrrrrrrrrrrrrrrrrr";
  3. }
  4.  
http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com
Littlehorse
All the world's a stage
Moderador
***
Desconectado Desconectado

Mensajes: 2.714


Nie Dam Sie


Ver Perfil WWW
Re: el porque del scanf no es recomendable
« Respuesta #4 en: 16 Mayo 2010, 21:52 pm »

¿Alguno sabe su equivalente en C++ o tendríamos que usar lo mismo?

Al igual que en C, si manejas las funciones correctamente no dejas basura en el buffer, pero en caso de hacerlo tenes por ejemplo cin.ignore(); entre otras.

Saludos
En línea

An expert is a man who has made all the mistakes which can be made, in a very narrow field.
-Ramc-


Desconectado Desconectado

Mensajes: 495



Ver Perfil
Re: el porque del scanf no es recomendable
« Respuesta #5 en: 16 Mayo 2010, 22:07 pm »

Funciones así hay varias, tenes esa setbuf, tenes __fpurge que es solo para *nix, etc.

Pero, lo mejor siempre es fgets + sscanf

http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.15.html

con fgets y sscanf lees, tomas lo que necesitas y desechas el resto, no tenes que preocuparte de que si el buffer está sucio o etc, porque no lo estará.
En línea


Shhh... be vewy, vewy, quiet!  I'm hunting wabbits...
LA PANDILLA MAS GRANDE DE MI CIUDAD, SE LLAMA POLICIA NACIONAL.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
recomendable o no?
Dudas Generales
xemnas 1 2,808 Último mensaje 23 Enero 2011, 16:01 pm
por Garfield07
bucle, se come el primer scanf
Programación C/C++
Neibar 4 3,208 Último mensaje 14 Junio 2012, 23:32 pm
por Neibar
Duda con scanf
Programación C/C++
Caster 3 4,213 Último mensaje 29 Septiembre 2012, 13:01 pm
por Caster
Pregunta de C scanf
Programación C/C++
g0rg3d3l4s3lv4 3 2,722 Último mensaje 15 Marzo 2013, 04:21 am
por g0rg3d3l4s3lv4
scanf y gets « 1 2 »
Programación C/C++
m@o_614 16 8,371 Último mensaje 21 Julio 2013, 19:29 pm
por rir3760
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines