Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Lotharsan en 15 Julio 2012, 10:27 am



Título: ¿porqué este programa símplemente no funciona?
Publicado por: Lotharsan en 15 Julio 2012, 10:27 am
/* 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.


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: DickGumshoe en 15 Julio 2012, 12:57 pm
¡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í:

Código
  1. #include <stdio.h>
  2.  
  3. main()
  4. {
  5.    int e, v;
  6.    char r='s';
  7.  
  8.    while(r=='s')
  9.    {
  10.        printf("Introduce la distancia recorrida: ");
  11.        scanf("%d", &e);
  12.        printf("Introduce la velocidad media: ");
  13.        scanf("%d", &v);
  14.        printf("El tiempo invertido ha sido %d\n", v/e);
  15.        printf("¿quieres repetirlo? ");
  16.        getchar();
  17.        r=getchar();
  18.    }
  19. }

Saludos!


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: do-while en 15 Julio 2012, 16:48 pm
¡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!


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: dato000 en 15 Julio 2012, 22:32 pm
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.

Código
  1.  
  2. #include <stdio.h>
  3.  
  4. int main(void)
  5. {
  6.    float e, v;
  7.    float res;
  8.    char r='s';
  9.  
  10.    while(r=='s')
  11.    {
  12.        printf("Introduce la distancia recorrida: ");
  13.        scanf("%f", &e);
  14.        printf("Introduce la velocidad media: ");
  15.        scanf("%f", &v);
  16.        res = v/e;
  17.        printf("El tiempo invertido ha sido %.2f\n", res);
  18.        printf("¿quieres repetirlo? ");
  19.        getchar();
  20.        r=getchar();
  21.    }
  22. }
  23.  
  24.  
  25.  

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


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: DickGumshoe en 15 Julio 2012, 22:39 pm
Citar
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.

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!


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: Lotharsan en 16 Julio 2012, 01:13 am
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?


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: DickGumshoe en 16 Julio 2012, 01:24 am
No, no lo han corregido... Pero bueno, con un simple getchar() se puede arreglar...


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: ApOkAlizE en 17 Julio 2012, 02:48 am
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.


Título: Re: ¿porqué este programa símplemente no funciona?
Publicado por: rir3760 en 19 Julio 2012, 18:45 pm
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
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:
Código
  1. do {
  2.   printf("Introduce la distancia recorrida: ");
  3.   scanf("%f", &e);
  4.  
  5.   printf("Introduce la velocidad media: ");
  6.   scanf("%f", &v);
  7.   printf("El tiempo invertido ha sido %.2f\n", v / e);
  8.  
  9.   printf("quieres repetirlo? ");
  10.   scanf(" %c", &r);
  11. }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