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

 

 


Tema destacado: Los 10 CVE más críticos (peligrosos) de 2020


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ¿Cómo funciona scanf() en este programa?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Cómo funciona scanf() en este programa?  (Leído 3,070 veces)
alfred_oh

Desconectado Desconectado

Mensajes: 3


Ver Perfil
¿Cómo funciona scanf() en este programa?
« en: 21 Febrero 2014, 16:03 pm »

Hola tengo el siguiente programa en c y la verdad no me queda muy claro de que manera afecta scanf() al buffer de teclado.


#include <stdio.h>

int main(void){
   int a;
   int b;
   printf("ingrese el valor de a: \n");
fflush(stdin);
   scanf("%d",&a);
fflush(stdin);
   printf("ingrese el valor de b: \n");
   scanf("%d",&b);
fflush(stdin);
   printf("\n a= %d\n",a);
   printf("\n b= %d\n",b);
return 0;
}


Yo lo que quiero es que mi programa lea el valor de a y el valor b por separado y luego lo saque por pantalla. El problema era cuando introducía para "a" varios números separados por espacio y apretaba enter p.e.: "1 2 3 4 5 \n" me imprimía a=1 y b=2. Por ahí leí que esto era porque lo último que introduzco por el teclado es enter, por lo tanto esa tecla se queda almacenada allí, en el buffer ¿Eso es así? ¿De que manera influye el hecho de introducir enter en el buffer del teclado? Estuve investigando y leí que la solución era vaciar el buffer para esto utilice fflush() pero creo que no funciona para vaciar este tipo de buffer. Así que seguí buscando y sugerían en un foro(de hace unos años atrás) utilizar "while(getchar()!='\n');" Modifiqué mi código y quedó así:


int main(void){
   int a;
   int b;
   printf("ingrese el valor de a: \n");
   scanf("%d",&a);
while(getchar()!='\n');
   printf("ingrese el valor de b: \n");
   scanf("%d",&b);
   printf("\n a= %d\n",a);
   printf("\n b= %d\n",b);
return 0;
}

Ya no tenía este problema. Lo que pasa es que tampoco entiendo como "while(getchar()!='\n');" me ayuda. Lo que entiendo que hace esa línea es "sacar del buffer" todos los símbolos menos el "\n", luego el símbolo que queda en el buffer de teclado es "\n", entonces realmente no esta vacío no? Alguien puede explicármelo porfavor! Gracias!


En línea

J.cE

Desconectado Desconectado

Mensajes: 13


Ver Perfil
Re: ¿Cómo funciona scanf() en este programa?
« Respuesta #1 en: 21 Febrero 2014, 16:45 pm »

no entendi muy bien, el primer codigo que pusiste funciona bien, excepto por que me parece que el primer fflush(stdin); esta de mas.
fflush(stdin); sirve para borrar el bufer del teclado entonces cunado tu escribas 1 2 3 4 5, scanf solo tomara hasta el primer espacio y los demas numeros quedan guardados en el buffer, aqui es donde entra fflush(stdin); borrando el buffer y evitando que estos se almacenen en el siguiente scanf

Código:
#include <stdio.h>

int main(void)
{
int a;
int b;
printf("ingrese el valor de a: \n");
scanf("%d",&a);
fflush(stdin);//para vaciar el buffer del teclado
printf("ingrese el valor de b: \n");
scanf("%d",&b);
fflush(stdin);//para vaciar el buffer del teclado
printf("\n a= %d\n",a);
printf("\n b= %d\n",b);
return 0;
}


En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: ¿Cómo funciona scanf() en este programa?
« Respuesta #2 en: 21 Febrero 2014, 17:31 pm »

tengo el siguiente programa en c
Lo primero que debes hacer es evitar el uso de fflush(stdin), las razones de ello en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

Al eliminarlo del programa tenemos:
Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.   int a;
  6.   int b;
  7.  
  8.   puts("Ingrese el valor de a:");
  9.   scanf("%d", &a);
  10.  
  11.   puts("Ingrese el valor de b:");
  12.   scanf("%d",&b);
  13.  
  14.   printf("a = %d\n", a);
  15.   printf("b = %d\n", b);
  16.  
  17.   return 0;
  18. }


Tomando ese programa como base ...


la verdad no me queda muy claro de que manera afecta scanf() al buffer de teclado.
Cuando utilizas scanf con el especificador "%d" lo que hace la funcion es:
1) Descarta el espacio blanco, por ello puedes introducir "       123" sin problemas.
2) Consume de la entrada estandar los caracteres que sean validos para la conversion en turno.
3) Al encontrar el primer caracter invalido (o una limitante en el especificador) ese caracter se queda intacto en la entrada estandar y se pasa a la siguiente conversion.

En tu programa si introduces:
Código:
    123    456{ENTER}
La primera llamada a scanf descarta el espacio blanco y consume los caracteres "123" para en base a ellos obtener el entero 123, el espacio inmediatamente despues del '3' causa el final de esa conversion y, al ser la ultima, el final de la llamada a scanf.

Para la segunda llamada a scanf el bufer de la entrada estandar contiene:
Código:
    456{ENTER}
Y la operacion es similar: scanf descarta los espacios, obtiene el entero  456 y el {ENTER} se queda en el bufer de la entrada estandar.

Modifiqué mi código y quedó así:

...

Código
  1. while (getchar() != '\n')
  2.   ;

...

Lo que pasa es que tampoco entiendo como "while(getchar()!='\n');" me ayuda. Lo que entiendo que hace esa línea es "sacar del buffer" todos los símbolos menos el "\n", luego el símbolo que queda en el buffer de teclado es "\n", entonces realmente no esta vacío no?
Por partes:

* Ese bucle descarta todos los caracteres incluyendo el '\n' ya que se puede leer como "Mientras el caracter leido NO sea '\n'" y, por supuesto, al leerlo se descarta.

* Como usualmente la entrada es por linea la intentencion de utilizar scanf y ese bucle es 1) Leer un entero con scanf y 2) Descartar el resto de la linea con el mentado bucle. Todo ello para evitar el comportamiento que mencionas.

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
alfred_oh

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: ¿Cómo funciona scanf() en este programa?
« Respuesta #3 en: 22 Febrero 2014, 10:15 am »

Muchas gracias por la explicación, sobre todo por la parte de "%d descarta los blancos". Con esa idea en la cabeza pude entenderlo fácilmente! Poniéndonos en otro situación, si por ejemplo introducimos:
" 123 {ENTER}"
En primer scanf lo que haría sería descartar el primer espacio y coger 123.
Luego el segundo scanf descartaría el segundo espacio, pero que hace con {ENTER}? Lo descarta también? Me imagino que si no? porque si no, no se quedaría esperando a que introduzcamos un número no? Entonces podríamos decir que %d descarta todo lo que no sea int?

PD: Gracias también por en enlace de "Lo que no hay que hacer en C/C++. Nivel basico"! Lo revisaré!
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: ¿Cómo funciona scanf() en este programa?
« Respuesta #4 en: 22 Febrero 2014, 18:23 pm »

Poniéndonos en otro situación, si por ejemplo introducimos:
" 123 {ENTER}"
En primer scanf lo que haría sería descartar el primer espacio y coger 123.
Luego el segundo scanf descartaría el segundo espacio, pero que hace con {ENTER}? Lo descarta también?

Si. Se descarta todo el espacio blanco antes de la conversión (espacio, tabulador, avance de linea, etc.).

Entonces podríamos decir que %d descarta todo lo que no sea int?
No porque eso puede llevar a confusiones. Es mejor decir que salvo "%c" y "%[]" con cualquier otro especificador (por ejemplo "%d", "%s", etc.) el espacio blanco al inicio no importa (ya que se descarta).

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
alfred_oh

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: ¿Cómo funciona scanf() en este programa?
« Respuesta #5 en: 25 Febrero 2014, 09:39 am »

Gracias por la aclaración! ;) Aprovecho para preguntar si también sería necesario este vaciado de BUFFER DE ENTRADA tras usar gets(), este caso sería diferente pues gets() lee hasta el final, es decir, hasta encontrarse con el símbolo '\n' no? Luego no haría falta vaciado no?
« Última modificación: 25 Febrero 2014, 09:46 am por alfred_oh » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
No me funciona este programa
Java
Meta 8 5,700 Último mensaje 22 Abril 2011, 07:42 am
por Meta
Emuhacker, quiero saber como funciona este programa
Ingeniería Inversa
jacalhacking 4 4,510 Último mensaje 12 Octubre 2011, 09:28 am
por jacalhacking
¿Como funciona este programa de C++?
Programación C/C++
Faceless 1 2,107 Último mensaje 2 Octubre 2015, 22:37 pm
por engel lex
como es posible que este programa funciona y como funciona?
Ingeniería Inversa
insider dealing 7 8,857 Último mensaje 1 Octubre 2017, 01:23 am
por BloodSharp
¿Cómo funciona este programa?
Programación C/C++
e 1 2,021 Último mensaje 23 Noviembre 2019, 21:05 pm
por MinusFour
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines