Como saber si es un bug de gcc? [Solucionado]

he creado el siguiente programita:

#include <stdio.h>

int show(int valor){
        char c; //con unsinged char tiene el mismo problema
        printf("iteración: %d - ingrese un caracter \n", valor);
        scanf("%c",&c);
        printf("caracter ingresado: %c\n",c);
        return 1;
}

int main(){
        int i=10;
        do{
                if(show(i)&1);
        }while(i--);

        return 0;
}

El problema se observa aquí (cuando lo ejecuto):

iteración: 10 - ingrese un caracter
h                                                           <----h es el caracter ingresado?
caracter ingresado: h
iteración: 9 - ingrese un caracter
caracter ingresado:                                        
                                                            <----debería pedirme ingresar un caracter?
iteración: 8 - ingrese un caracter
o                                                           <----o es el caracter ingresado
caracter ingresado: o
iteración: 7 - ingrese un caracter
caracter ingresado: 
                                                            <----debería pedirme ingresar un caracter?
iteración: 6 - ingrese un caracter
l                                                           <----l es el caracter ingresado
caracter ingresado: l
iteración: 5 - ingrese un caracter
caracter ingresado:
                                                            <----debería pedirme ingresar un caracter?
iteración: 4 - ingrese un caracter
a                                                           <----a es el caracter ingresado
caracter ingresado: a
iteración: 3 - ingrese un caracter
caracter ingresado:
                                                            <----debería pedirme ingresar un caracter?
iteración: 2 - ingrese un caracter

....

lo he compilado con "gcc if.c -o if" ; "if.c" es el fichero fuente
no entiendo si se salta una linea por que es un problema del gcc o por que hay algo mal en mi código(seguramente es esto ultimo).

nota: el programa en si no tiene mucho sentido, pero resume algo de lo que estoy usando para la comunicación serie.

¿Como puedo saber cual es el problema? ¿no se si a alguien le paso esto?

gracias.

fernando

perdon, me olvidaba de algunos datos:

fernando@hp:~/programacion/kk/pruebasc$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.4-7' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.4 (Debian 4.4.4-7)

jejeje no te voy a hacer sufrir que es año nuevo :)

Prueba así (verás que funciona)

int show(int valor){
        char c[1];
        printf("iteración: %d - ingrese un caracter \n", valor);
        scanf("%s",&c);
        printf("caracter ingresado: %s\n",c);
        return 1;
}

Y luego intenta razonar el salto, fíjate qué teclas pulsas. Poniendo un "wait (1);" antes y después del scanf igual te ayuda a verlo. Y recuerda que C es el lenguaje de alto nivel de más bajo nivel.

gracias chacal por responderme, la buena onda, y perdón (seguro que debe ser algo muy simple y no lo veo): lo tuyo anda bien, he incluso así también anda:

int show(int valor){
        char c;   //sin el tamaño
        printf("iteración: %d - ingrese un caracter \n", valor);
        scanf("%s",&c);
        printf("caracter ingresado: %s\n",c);
        return 1;
}

veo que cuando se usa "%c" toma el enter como otro caracter mas y repite el scanf.

viendo las página man de la función scanf(), dice sobre el %c y %s:

       s      Concuerda  con  una secuencia de caracteres distintos de blancos; el siguiente puntero debe serlo a char, y el vector debe ser lo suficientemente grande como para aceptar toda la secuencia y el carácter 0 ó NUL final.  El análisis de  la  cadena de entrada acaba en el siguiente espacio blanco o cuando se llega a la anchura de campo máxima, lo que ocurra antes.

       c      Concuerda  con  una  secuencia de anchura caracteres (1 por omisión); el siguiente puntero debe serlo a char, y debe haber suficiente espacio para todos los caracteres (no se añade el carácter NUL terminador).  Se  suprime  el  descarte  de  los blancos iniciales. Para saltar un espacio en blanco inicial, emplee un espacio explícito en el formato.

Bueno, parece que el "s" concuerda con lo que pones en la respuesta(char c[1]), cortaria por que al entrar con el enter excede el tamaño.
Pero cuando el scanf con el %c lee un caracter, por que me lee todos los que están a continuación, incluso el enter.

he probado lo que me sugeriste, simplifique un poco ese programa en:

#include<stdio.h>

int main(){
        char c;
        printf("\nIngresando un caracter\n");
        scanf("%c",&c);
        wait(10);
        printf("\nIngresando un caracter\n");
        scanf("%c",&c);
        wait(10);
        printf("\nIngresando un caracter\n");
        scanf("%c",&c);
        return 0;
}

y cuando salta ingreso el primero y le hago enter se me saltea un scanf;

Algo mas, en caso de querer entrarle un caracter no imprimible por ejemplo "alt+ctrl y 13" (0x13 en ascci) no me lo toma, bueno no es parte del problema inicial pero por ahí te encontraste con ese problema te agradezco alguna idea.

fernando

Diculpas a:

Offtopic:

Creo que no deberías suponer un bug en un compilador tan a la ligera, a mi parecer es un tanto arrogante.

Borré el comentario sin querer.

Respuesta: No, ni un tanto arrogante, ni un poquito arrogante, puede ser que he metido la pata (algo así como la mitad) en el titulo. No es arrogante por que está como una pregunta, no como una afirmación. No podría afirmar que es un bug por que no tengo criterios para decir tal cosa, es mas estoy años luz de los tipos que hacen el gcc.

Ahora, cuando describí el problema puse:

...
no entiendo si se salta una linea por que es un problema del gcc o por que hay algo mal en mi código(seguramente es esto ultimo).
....

tal vez hubiera sido mas sensato poner primero la parte resaltada en negrita y lo del bug ultimo.

Para terminar, por que me estoy saliendo a otra cosa, te pregunto: Por que no preguntarse es un bug?. Claro, el control y cuidado de gcc es tanto como el del kernel de linux. Ojo afirmar que es un bug sería algo mas que arrogante de mi parte, pero preguntarse como saber si es un bug, o directemente decir " es un bug?", cual es el criterio?; veo un comportamiento que creo que no debería estar, como puedo saber si es un bug? o que puede ser?, etc (puede ser también que estoy suponiendo mal de como debería funcionar lo que estoy viendo).

Es el problema de las matemáticas, unos tipos que dicen saber saber, pero cuando uno quiere saber como piensan un problema, o porqué está mal planteado, o creen que la inteligencia es algo místico y un montón de cosas ajenas a los números, que lo único que logran con esa forma de pensar complicar mas las cosas, (también hay palos para los otros: literatura, etc, e incluso en los cursos de programación donde la mayoría marchan con la filosofía windows). Aclaro que no todo el mundo es igual.

Al meter un carácter y a continuación un intro, estás metiendo 2 caracteres porque tienes que incluir el intro. En el do-while que tienes si metes como carácter 1234567890 seguramente tragará el bucle entero, y verás como en cada iteración del bucle cogerá el carácter correspondiente en el orden de inserción que le has dado.

Si quieres capturar código hexadecimal, se lo tendrás que decir explícitamente al scanf, si estás "escuchando" caracteres char (c) o string (s), cualquier cosa que se puede representar como un carácter de ese tipo lo recogerá (eso incluye intros, espacios y demás), y lo irá metiendo secuencialmente en el programa.

Las cadenas de caracteres y los búferes dan muchos problemas. No es debido a bugs del gcc ni a errores del código, es simplemente que están mal paridos. Es mi punto de vista, ojo, que sólamente tengo un cerebro de los del montón.

La función __ffpurge (dos guiones bajos, más información en la página man) te va a solucionar el problema aunque tiene sus limitaciones porque no es portable. Tienes otras como fflush y fpurge pero no son igual de eficientes.

gracias por la respuesta, pero el ffpurge me parece que mas si me quiero meter con el puerto serie en linux, por los argumentos que le tengo que pasar,

exactamente lo que estoy intentando hacer es para un microcontrolador(mc9s12ne64), mi idea era hacer un control de flujo XON-XOFF solo half-duplex. pero el tema del scanf venia a que no conozco todavía como debugear el código que estoy escribiendo, así que se me ocurrió simular el cambio de estado de los registros ingresandolos con el scanf corriendo el programa este en linux directamente. verán:

/*SCI*/
static inline int SCI1_get(byte *value) {
/*simulando...*/
byte SCI1_SR1;
printf("**rx: get de un value del puerto -1- RDRF - 2-error - 0 continua\n");
scanf("%s",&SCI1_SR1);
/**/

if(SCI1_SR1 & (OR_NF_FE_PF)){
/*simulando...*/
byte SCI1_SR1;
printf("**rx: ERROR\n");
/**/

return SCI_ERROR;
}else if(SCI1_SR1 & RDRF){
/*simulando...*/
byte SCI1_SR1;
printf("**rx: EMPTY\n");
/**/
return SCI_RXEMPTY;
}

/*simulando...*/
printf("**rx: get de un value del puerto, RDH\n");
scanf("%s",&SCI1_RDH);
/**/

*value = SCI1_RDH;
return SCI_OK;
}

static inline int SCI1_put(byte value){
/*simulando...*/
byte SCI1SR1_TDRE;
byte SCI1_DRL;
printf("**tx: ingresate (value:%c)el TDRE 1- esta full 0- sigue bien\n",value);
scanf("%d",&SCI1SR1_TDRE);
/**/

if(SCI1SR1_TDRE){
printf("**tx: TXFULL - ERROR\n");
return SCI_TXFULL;
}
SCI1_DRL=value;

/*simulando...*/
printf("**tx: Enviando el caracter desde el DRL:%c\n",SCI1_DRL);
/**/

return SCI_OK;
}

bueno eso es solo parte para enviar y recibir (tengo que corregir algo ahí todavía), después esta la parte del buffer y etc. Después postearé el código entero, pero en un hilo a parte, cuando lo termine y lo pruebe bien. calculo que el fin de semana que viene lo tendré.