¿porqué este programa símplemente no funciona?

Iniciado por Lotharsan, 15 Julio 2012, 10:27 AM

0 Miembros y 2 Visitantes están viendo este tema.

Lotharsan

/* Programa que calcula el tiempo de conducción dada la distancia y la velocidad media.
Utiliza un bucle cuando se le pregunte al usuario si quiere repetirlo y conteste que sí usando un bucle while. */

#include "stdio.h"

main()
{
    int e, v;
    char r='s';

    while(r=='s')
    {
        printf("Introduce la distancia recorrida: ");
        scanf("%d", &e);
        printf("Introduce la velocidad media: ");
        scanf("%d", &v);
        printf("El tiempo invertido ha sido %d\n", v/e);
        printf("¿quieres repetirlo? ");
        r=getchar();
    }
}

----------------------------------------------------------

Lo ejecuto tanto en Ubuntu como con un compilador en Android (c4droid). El resultado siempre es el mismo, no me leer el último getchar y por tanto el while no se ejecuta.
En la mayoría de libros hacen referencia a conio.h, librería no standar de Borland. Yo por supuesto quiero realizar la tarea de leer un caracter desde el teclado de forma standar a todos los compiladores, pero no me funciona. ¿cuál es la forma correcta para leer un caracter desde teclado? También he intentado incluso usar un scanf("%c", &r)..... sin mayor éxito.

DickGumshoe

¡Hola!

La función scanf deja "basura" en el buffer del teclado, y por eso el getchar() coge la "basura" que tenía. La solución sería poner un getchar() antes de r=getchar(), para que el primero obtenga la basura y ya con el segundo puedas escribir. Así:

#include <stdio.h>

main()
{
   int e, v;
   char r='s';

   while(r=='s')
   {
       printf("Introduce la distancia recorrida: ");
       scanf("%d", &e);
       printf("Introduce la velocidad media: ");
       scanf("%d", &v);
       printf("El tiempo invertido ha sido %d\n", v/e);
       printf("¿quieres repetirlo? ");
       getchar();
       r=getchar();
   }
}


Saludos!

do-while

¡Buenas!

Otro detalle, para dar el tiempo estas dividiendo dos enteros, asi que estas truncando el valor real. Hazle un cast a float a alguna de las dos variables e imprime el valor como si fuese float, no int.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

dato000

pues para evitar ese problema del scanf con el buffer de memoria (que almacena basura por el enter que le da uno en la entrada de la instrucción si no estoy mal) simplemente se crea una variable que almacene la división y se imprime, es mejor hacer eso, es más practico y a la larga deja las cosas mucho más entendibles.



#include <stdio.h>

int main(void)
{
    float e, v;
    float res;
    char r='s';

    while(r=='s')
    {
        printf("Introduce la distancia recorrida: ");
        scanf("%f", &e);
        printf("Introduce la velocidad media: ");
        scanf("%f", &v);
        res = v/e;
        printf("El tiempo invertido ha sido %.2f\n", res);
        printf("¿quieres repetirlo? ");
        getchar();
        r=getchar();
    }
}




Personalmente me gusta más un do-while, pero pues así funciona también.



DickGumshoe

Citarpues para evitar ese problema del scanf con el buffer de memoria (que almacena basura por el enter que le da uno en la entrada de la instrucción si no estoy mal) simplemente se crea una variable que almacene la división y se imprime, es mejor hacer eso, es más practico y a la larga deja las cosas mucho más entendibles.

Pero ahí sigues poniendo el getchar()... Que cree una variable o no no influye (es más, si ese dato no lo va a necesitar después sería un desperdicio de memoria crear una variable solo para eso...)

Saludos!

Lotharsan

Muchas gracias por las respuestas.... me han servido de mucho.
Aunque ahora me ha quedado la duda de porqué una función como scanf or getchar no se hicieron ya contemplando esta situación en la que leen datos residuales o símplemente no se les añadió la opción de eliminar datos residuales después de haber leido la información, aunque eso no se pensara en el momento de la creación de estas funciones ¿no han pasado ya años como para haberse corregido o creado una forma mejor de introducir la información sin que se produzcan estos casos?

DickGumshoe

No, no lo han corregido... Pero bueno, con un simple getchar() se puede arreglar...

ApOkAlizE

#7
Pues eso mismo me digo yo... lo podrian haber corregido, pero bueno en esta situación como es tan fácil como poner un getchar() almenos no genera problemas mayores.
Los virus informaticos son como las personas, hacen lo posible para destruir y hacen lo impossible para no ser destruidos... - ApOkAlizE

rir3760

Cita de: Lotharsan en 16 Julio 2012, 01:13 AMAunque ahora me ha quedado la duda de porqué una función como scanf or getchar no se hicieron ya contemplando esta situación en la que leen datos residuales o símplemente no se les añadió la opción de eliminar datos residuales después de haber leido la información
Ese no es el problema.

Los dolores de cabeza se deben al uso intercalado de funciones que no ignoran el espacio blanco (getchar/fgets/etc.) con funciones que usualmente si lo hacen como scanf o fscanf.

En lugar de llamar a "getchar" para descartar un carácter puedes utilizar scanf para leer los tres datos:
do {
   printf("Introduce la distancia recorrida: ");
   scanf("%f", &e);

   printf("Introduce la velocidad media: ");
   scanf("%f", &v);
   printf("El tiempo invertido ha sido %.2f\n", v / e);

   printf("quieres repetirlo? ");
   scanf(" %c", &r);
}while (r == 's' || r == 'S');

Con el espacio en " %c" nos aseguramos de descartar la secuencia de espacio blanco a continuación del numero indicando la velocidad.

De nuevo solo es cuestión de manejar bien las funciones. Y si eso no basta se puede desarrollar una propia (y a la medida).

Un saludo
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