Empezando en C y con problemas que google y el libro no me solucionan.

Iniciado por Lotharsan, 22 Marzo 2012, 20:26 PM

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

Lotharsan

Estoy empezando con C, siguiendo el libro "Guia de autoenseñanza" de Herbert Schildt con Code::Blocks en Ubuntu 11.10.

Realizo los ejercicios del libro y empiezo teniendo problemas con las librerias, como conio.h, la cual he encontrado en google que puedo sustituir con ncurses.h...

Cuando realizo un simple programa y en el libro usan getche() yo uso getchar();
pero he aquí mis problemas...

en un programa simple como:

/* Programa que lee diez letras. Después de que haya leído las letras, muestra la que está en primer lugar en el alfabeto (la que tiene menor valor) de las introducidas. */

#include "stdio.h"

main()
{
    char ch, menor='z';
    int i;

    for(i=1; i<11; i++)
    {
       printf("Introduce la letra número %d: ", i);
       ch = getchar();
       if(ch<menor) menor=ch;
    }

    printf("La letra de menor valor introducida ha sido %c", menor);
}



Diréctamente me salta siempre un getchar(), haciendo solo la 1ª, 3ª... y llenando con un espacio en blanco ch en la 2ª, 4ª....

buscando en google encontré como limpiar el buffer antes del getchar... pero que si quieres arroz Catalina.... el programa hace exáctamente lo mismo....

No queriendo estancarme horas buscando un porqué sigo con el siguiente ejercicio:


/* Programa que alcula el área de un círculo, rectángulo o triángulo utilizando una escalera if-else-if */

#include "stdio.h"

main()
{
    int b, a;
    float r;
    char op;

    printf("¿qué área quieres calcular? Rectángulo, Triángulo o Círculo: ");
    fflush(stdin);
    op = getchar();

    if(op=='R'||'r')
    {
        printf("Introduce la base: ");
        scanf("%d", &b);
        printf("Introduce la altura: ");
        scanf("%d", &a);
        printf("El área del rectángulo es: %d", b*a);
    }
    else if(op=='T'||'t')
        {
            printf("Introduce la base: ");
            scanf("%d", &b);
            printf("Introduce la altura: ");
            scanf("%d", &a);
            printf("El área del triángulo es: %d", (b*a)/2);
        }
        else if(op=='C'||'c')
            {
                printf("Introduce el radio: ");
                scanf("%f", &r);
                printf("El área del círculo es: %f", 3.141592*r*r);
            }

}



y he aquí que el programa decide que da igual si a la hora de introducir un caracter por teclado le introduces una T, una C..... porque solo realiza el primer if...

¿dónde está todo el problema este de lidiar con este editor, o sistema o son las funciones, compilador, librerias.....? ya me lo empiezo a plantear todo....

¿alguna ayuda?

durasno

Hola Lotharsan! La libreria conio.h no es estandar, solo lo podes utilizar en window, por eso tenes problemas en Ubuntu. Mas adelante si queres investiga acerca de ncurses pero por ahora no t lo recomiendo.
Antes de pasar a los codigos vi algo comun en los dos programas, q es: #include "stdio.h". A menos q hayas creado tu propia libreria( cosa q no creo) el include deberia ir asi #include <stdio.h>... Ahora los codigos:
Para solucionar el problema del getchar(), al lado pone fflush(stdin); limpia el bufer utilizado por el teclado, en este caso limpiaria el enter (algunos expertos dicen q es mala practica usar fflush pero en un ejercicio tan simple no veo el inconveniente :))

Para el segundo programa siempre toma el primer if xq tenes mal las condiciones. Deberia ser:
if(op=='R'||op=='r')
else if(op=='T'||op=='t')
else if(op=='C'||op=='c')

Espero te sirva mi respuesta, saludos
Ahorrate una pregunta, lee el man

Lotharsan

Gracias por la respuesta.... en cuanto al #include, en el libro que menciono viene explicado que puedo introducir la libreria entre comillas como me indicas, y el compilador me lo acepta sin problemas.
De todas formas he probado tu opción y el resultado no varía.... sigue pasando lo mismo después de añadir el fflush(stdin); que como ya había mencionado
Citarbuscando en google encontré como limpiar el buffer antes del getchar... pero que si quieres arroz Catalina.... el programa hace exáctamente lo mismo....
incluso después del getchar(), sigue dando el mismo resultado nefasto.... no entiendo porqué realiza ese salto a cada repetición.

y en cuanto al segundo programa.... tienes toda la razón... muchas gracias.

Me sigue quedando la duda del primer programa. Agradezco cualquier consejo.

durasno

Hola! que raro que siga pasando lo mismo con el fflush despues del getchar, lo probe yo y me anduvo normal.. Bueno te explico mas o menos el error nefasto q te da el getchar(aunq creo q ya lo sabes): cuando vos ingresas un caracter,ej 'x', por teclado inmediatamente ingresas el ENTER el cual tambien es un caracter, entonces tanto el caracter 'x' como el ENTER se almacenan en el bufer del teclado. En la primera llamada a getchar lo que va a hacer es agarrar ese primer caracter 'x' y almacenarlo en ch, luego en el siguiente ciclo del for getchar va a agarrar el caracter ENTER y tambien lo va a almacenar en ch. Es por esto q solo podes ingresar caracteres en el 1º, 3º, 5º... getchars

Como dijist q ch=getchar();fflush(stdin); no te funciona proba con lo siguiente:
scanf("%c",&ch);getchar();
El %c es para ingresar caracteres. Lo malo de ingresar caracteres con scanf es que tambien se almacena el ENTER, es por eso que pongo el getchar, para que lo tome del bufer

Espero se haya entendido algo, no soy muy bueno explicando

Saludos
Ahorrate una pregunta, lee el man

Lotharsan

Hola,
Gracias por la respuesta....
No es una solución óptima, pero sabiendo que no es correcto pero permitiendome seguir con los ejercicios, he optado por realizar lo que me has aconsejado, vaciando el buffer y poniendo un segundo getchar().... de esta forma sí que realiza los pasos a seguir...

No sé si será por el compilador usado en el sistema que uso, aunque sospecho que los tiros van por ahí....

Gracias de todas formas, con esto puedo continuar.

do-while

#5
¡Buenas!

fflush SOLO SE DEBE UTILIZAR SOBRE FLUJOS DE SALIDA. El funcionamiento sobre flujos de entrada queda indefinido.

En sistemas GNU/Linux, no te va a vaciar el buffer de entrada. Lo que te esta sucediendo es que despues de cada tecla estas pulsando intro, y este queda en la entrada, por lo tanto, el siguiente getchar te leera ese intro y pasara a leer el siguiente par letra+intro.

Despues de realizar cualquier lectura de teclado que sepas que no elimina el salto de linea que introduces al pulsar intro, tienes que terminar de leer la entrada, asi cuando llegue la siguiente lectura no tendras problemas ni comportamientos imprevistos. Utiliza este codigo para terminar de leer la entrada:


int c;

//tu lectura
//y ahora vacias el buffer de entrada
while((c = getchar()) != '\n' && c != EOF);


Lo que acabamos de hacer es leer hasta que encontremos un salto de linea o hasta que llegue EOF. Lo primero que suceda.

Por cierto, no es que conio sea especifica de windows, es especifica de Borland.

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

Lotharsan