Ver Mensaje Individual
  #4 (permalink)  
Antiguo 13/07/2013, 07:54
vosk
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Problema en el bucle while

Lee datos del stream de entrada hasta dar con un salto de linea; lo de 'leer' con el stdin significa copiar el caracter en un bufer y quitar de la cola, la finalidad de esta funcion no es saber lo que hay en la cola del stdin sino vaciarlo haya lo que haya, para que el siguiente 'scanf' o 'getchar' u otro no se encuentre con el salto de linea como primer caracter porque eso implica (segun la logica de la funcion scanf) que el usuario ha aceptado la entrada pinchando un enter, y como el anterior 's_n' es diferente de 'n' siempre repite. En este caso solo lee hasta dar con el primer salto de linea, puedes implementar para que lea hasta el EOF (eso vaciará completamente el stdin)

En el segundo scanf sabiendo que el primero te deja un salto de linea como primer elemento de lectura puedes forzar la lectura de un salto de linea seguido del caracter que te interesa

Código C:
Ver original
  1. scanf("\n%c", &s_n);

Dicho de otra forma, inicias la aplicacion y stdin está vacio. Pides tres numeros en formato senar + espacio + senar + espacio + senar, el usuario los entra (los entra correctamente, sin poner a prueba la aplicacion usando caracteres textuales en vez de numericos),
de forma que teclea el valor '2' y el stdin queda como [2], teclea un espacio y stdin queda como [2][SP], teclea 3 y stdin queda [2][SP][3], teclaea espacio, teclea un 4 y pincha enter; ahora mismo en stdin hay (**)

[2][SP][3][SP][4][CR] //SP es espacio, CR es carriage return alias enter

La funcion scanf va leyendo mientras haya algo en la cola, es decir que cuando tecleas el primer '2' ya está funcionando el scanf hasta completar el formato o hasta dar con el salto de linea (lo que antes ocurra detiene el proceso). Va copiando los datos a los buffers proporcionados y va quitando de stdin lo que copia

stdin = [2][SP][3][SP][4][CR]

Primero copia el 2 en &a, luego lee SP pero no lo copia porque no le proporcionas bufer de destino (podrias darle un %c despues del %lf y saltarte los espacios), ahora en stdin queda [3][SP][4][CR], sigue leyendo ahora copia 3 en &b, salta el SP, copia 4 en &c y finaliza porque ha completado el formato que le pediste, de forma que al final stdin = [CR]

(**)(en verdad en el momento que tecleas '2', scanf la copia a &a y se elimina de la cola y cuando vas a teclear el primer espacio el '2' ya no está y la cola está vacía, es decir que nunca hay una cola [2][SP][3][SP][4][CR], pero lo pongo asi como vision atemporal o como quieras decirlo, son todos los caracteres en el orden en que aparecen en la cola del stdin)

Despues de eso determinas la media, la muestras y preguntas si quiere repetir. Llamas a scanf y sabiendo que stdin aun tiene el ultimo [CR] que no leyó, sabiendo tambien que scanf lee mientras haya algo en la cola, y sabiendo que scanf finaliza cuando completa el formato o cuando encuentra CR (lo que antes ocurra), en el scanf para entrar 's/n' no guardas en 's_n' el caracter 's' o 'n' sino el '\n' [CR] que quedó como ultimo caracter el la cola del stdin ok?

Con 'buida_bufer_teclat()' lees y quietas de la cola ese \n que te hace saltar el scanf cuando buscas un caracter.

Saludos
vosk