Author Topic: ¿Cómo funciona scanf() en este programa?  (Read 2919 times)

alfred_oh

  • Newbie
  • *
  • Posts: 5
  • Karma: 0
    • View Profile
¿Cómo funciona scanf() en este programa?
« on: Febrero 21, 2014, 10:03:54 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!

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5472
  • Karma: 12
    • View Profile
    • Apuntes de programación
Re: ¿Cómo funciona scanf() en este programa?
« Reply #1 on: Febrero 21, 2014, 10:41:25 pm »
Hola:

Cuando pulsas retorno, se pasan los caracteres de la línea a scanf(). scanf() lee lo que le pides, pero no lee mas. Si en una linea escribes varios numeros separados por espacios, estilo 1 2 3 4 5, cada scanf("%d%) ira leyendo uno de esos números, pero dejará sin tocar el resto, por eso tienes a=1 y b=2.

Si solo quieres leer un número por línea, lees el primero y luego con un bucle lees el resto hasta el \n, tirando todo, que es lo que has hecho en el segundo caso.

El fflush sirve para streams de salida. Para un stream de entrada no está definido su comportamiento, puede hacer cualquier cosa, desde descartar el resto de lo que queda de entrada (que es lo que pretendias) a no hacer nada (que es lo que parece que te esta pasand) http://www.cplusplus.com/reference/cstdio/fflush/

Se bueno.

alfred_oh

  • Newbie
  • *
  • Posts: 5
  • Karma: 0
    • View Profile
Re: ¿Cómo funciona scanf() en este programa?
« Reply #2 on: Febrero 22, 2014, 04:01:28 pm »
Gracias por responder! Ok, ahora lo entiendo mejor, me estoy adentrando en la programación en C y tengo la cabeza llena de dudas. ¿Cuándo dices stream de salida te refieres a la pantalla de terminal de Linux, por ejemplo? Podrías decirme o darme un ejemplo de en que caso se utilizaría fflush? Gracias =)

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5472
  • Karma: 12
    • View Profile
    • Apuntes de programación
Re: ¿Cómo funciona scanf() en este programa?
« Reply #3 on: Febrero 22, 2014, 05:48:57 pm »
Hola:

Un stream de salida es cualquier sitio donde tu escribes datos. Puede ser la stdout (escribir datos en la pantalla), un fichero, un socket, etc.

A veces esos stream guardan los datos temporalmente en memoria y no los escriben realmente en su destino (pantalla, fichero, ...) ya que la escritura en estos dispositivos suele ser costosa y es más eficiente escribir muchos datos de una sola vez, que escribir pocos datos en muchas veces. Me explico, si se accede una sola vez al disco para meter en un fichero un texto "hola", es más eficiente que si se escribe cuatro veces en el disco para escribir las letras "h", "o", "l" y "a" de una en una. Por ello, los streams suelen guardar lo que les dices en memoria y cuando tienen suficientes datos los escriben realmente en disco, pantalla.

fflush lo que hace es forzar la escritura real en el dispositivo (pantalla, disco) de lo que el stream tiene guardado en memoria. No debería usarse por costumbre ya que perderías la eficiencia que tratan de conseguir los streams. Deberías usarlo solo cuando necesites que de forma inmediata se escriban esos datos realmente en el dispositivo que sea.

Un ejemplo típico es un printf("hola") sin retorno de carro. stdout guarda lo que tiene que escribir hasta que le llega un retorno de carro \n para hacer la escritura real. Si hicieras un printf("hola") no verías nada en pantalla hasta que escribas el retorno de carro. Si necesitas visualizar ese texto sin \n , debes hacer el fflush(stdout)

Se bueno.
« Last Edit: Febrero 22, 2014, 05:52:08 pm by chuidiang »

alfred_oh

  • Newbie
  • *
  • Posts: 5
  • Karma: 0
    • View Profile
Re: ¿Cómo funciona scanf() en este programa?
« Reply #4 on: Febrero 25, 2014, 03:55:55 pm »
Gracias por la explicación! Ahora lo entiendo mejor y me da que por ahora no tendré que utilizar fflush() ya que recién estoy empezando...

 

ey