Resultados 1 al 9 de 9

Tema: Empezando con C .. resultados diversos

  1. #1

    Predeterminado Empezando con C .. resultados diversos

    Buenas,

    Estoy empezando con C, y uso el compilador GCC (4.6.1). Linux.

    Ocurre algo muy raro, y es que un mismo fichero de texto ante diversas compilaciones seguidas y ejecuciones, los resultados son diversos.
    Esta es mi primera pregunta: ¿Habéis experimentado ese tipo de acontecimientos? ¿Creéis que es debido al gcc? ¿Debería de cambiar de compilador?
    A algún compañero le ha pasado lo mismo. Y no sé si será coincidencia, pero en alguna ocasión el cerrar el gedit (con el que edito el archivo .c) y la consola y abrirlos de nuevo daba un resultado distinto tras compilar y ejecutar de nuevo.

    Por otro lado, un tipo de resultado que es muy raro, a ver si me podéis decir en qué falla:
    main2.c
    Código:
    #include <stdio.h>
    
    int main(int argc, char *argv[]){
    
        int d;
        int val = scanf("%d", &d);
        val = scanf("%d", &d);
        printf("%d\n",val);
        printf("%d\n",scanf("%d", &d));
    
        return 0;
    }

    ejecución
    Código:
    user@userpc:~/Desktop$ gcc main2.c
    user@userpc:~/Desktop$ ./a.out 
    12
    25
    1
    56
    1
    user@userpc:~/Desktop$ ./a.out 
    abc
    0
    0
    A mi modo de ver aquí hace algo raro:
    -si meto número funciona como debe.
    -Pero si meto letras, devuelve 0 (scanf) y hasta ahí bien, pero no tiene que mostrarlo. Y él lo muestra (el primer 0). Y luego muestra otro 0 (que ya no sé de cual es ese último 0, porque supuestamente hay más scanf que no pide), saltandose dos lineas de scanf (y las dos deberían mostrar el valor, y no la primera).

    main3.c
    Código:
    #include <stdio.h>
    
    int main(int argc, char *argv[]){
    
        int d;
        int val = scanf("%d", &d);
    
        if (val == 1){
            printf("%d\n", d);
        }else if ( val == 0){
            puts("Failed Conversion");
        }else{ // == EOF
            puts("EOF: Input failure");
        }
    
        
        while (scanf("%d", &d) != 1)
            ;    
        printf("%d\n", d);
        
        return 0;
    }
    ejecución
    Código:
    user@userpc:~/Desktop$ gcc main3.c
    user@userpc:~/Desktop$ ./a.out 
    12
    12
    25
    25
    user@userpc:~/Desktop$ ./a.out 
    ab
    Failed Conversion
    ab
    ab
    ab
    12
    3
    4
    5
    6
    jk
    12
    ^C
    -Primera ejecución todo correcto al meter números.
    -Segunda ejecución: En este caso vemos como con el primer if else encadenado funciona correctamente, pues cuando meto letras (retorna 0 y muestro el mensaje), pero luego, debería estar pidiendo hasta que no insertemos algo incorrecto (letras por ejemplo), y salirse del bucle cuando ponga un digito, por ejemplo, pero no lo hace. Como véis tengo que interrumpir la ejecución (Ctrl+C).

    Un saludo.

  2. #2

    Predeterminado Re: Empezando con C .. resultados diversos

    Quizás es que scanf como retorna la cantidad de items procesado, no siempre retorne 1 en caso correcto, simplemente que sea distinto de cero, y distinto de EOF.
    Te recomiendo que depures paso a paso tu programa para ver que ocurre.

  3. #3
    Con domicilio en Noticias3d.com Avatar de Black_ice_Spain
    Ubicación
    Cantabria/BCN
    Edad
    24
    Mensajes
    6,114

    Predeterminado Re: Empezando con C .. resultados diversos

    el gcc no tiene la culpa, por eso respira tranquilo, y más en programas tan simples.

    Por cierto:


    printf("%d\n",scanf("%d", &d));

    ese scanf que yo sepa no te va a retornar &d para que lo uses en el printf, retornará "algo" (el nº de caracteres?). El valor que tu quieres está en &d
    Última edición por Black_ice_Spain; 05/05/2012 a las 12:25

    GPU
    :7850 1gb@1100 CPU:I5 2500K@4.6 Placa: Asrock Z77 Pro3Memory: 8gb 1600 Sonido: Xonar DG/CAL!Monitor:BENQ BL2400PT Caja: Antec Lanboy

  4. #4

    Predeterminado Re: Empezando con C .. resultados diversos

    Tras estar unas cuantas horas para determinar un buen debugger... aunque ninguno me convence del todo, ya he podido ver lo que deseaba.

    Respecto de las letras, da igual que meta 1 o más, siempre ocurren hechos extraños.
    Respecto a los números, siempre estoy metiendo numeros seguidos, luego se considera 1 para devolución de scanf, por lo que por eso no hay problema.
    Tiene que ser otra cosa.

    Debuggeando puedo ver:
    En el main2.c hace lo siguiente:
    primer scanf() meto letras
    el siguiente scanf le obvia (pasa por la instruccion pero no veo que me pida nada por consola)
    continua al printf y muestra el resultado del primer scanf que si introduje letras
    continua al printf con scanf pero no me pide nuevo dato con ese scanf, directamente muestra el printf de la primera vez.

    ¿Por qué ocurre eso?

    Es muy sencillo de ver cómo esta cascando, si no es del gcc, ¿de quién es el problema?.



    Edito después de que tu edites:
    ya ya, no caigo en ese error tan tonto, lo que quiero mostrar es 1 o 0 segun haya salido bien o haya errores.

  5. #5
    Con domicilio en Noticias3d.com Avatar de Black_ice_Spain
    Ubicación
    Cantabria/BCN
    Edad
    24
    Mensajes
    6,114

    Predeterminado Re: Empezando con C .. resultados diversos

    prueba con una version mas santigua del gcc, pero dudo mucho que sea él, sino del scanf.
    Por cierto, ten en cuenta que un entero se inicializa a 0, por lo que si metes letras, es normal q muestre 0.
    Última edición por Black_ice_Spain; 05/05/2012 a las 13:41

    GPU
    :7850 1gb@1100 CPU:I5 2500K@4.6 Placa: Asrock Z77 Pro3Memory: 8gb 1600 Sonido: Xonar DG/CAL!Monitor:BENQ BL2400PT Caja: Antec Lanboy

  6. #6

    Predeterminado Re: Empezando con C .. resultados diversos

    Probaré con otra versión de gcc si no hay más respuestas. He probado con g++ y hace lo mismo.
    He intentado buscar donde está el codigo fuente de scanf y no lo he encontrado (pensaba que en stdio.h, pero no es necesario hacer el include puesto que lo carga por su cuenta). pero no sé desde donde.

    Lo de que el entero se inicialice a 0, y meter letras, sigo diciendo que lo que muestro es 1 o 0 (o como mucho EOF) puesto que lo que me interesa no es lo que meto sino si lo que he metido es válido (>=1) o no (<1).

    Aquí otra prueba muy sencilla, lo podéis probar en vuestra casa y ver si funciona o no:



    #include <stdio.h>

    Código:
    int main(int argc, char *argv[]){
    
    	int d;
    	int p;
    	do
    	printf("%d",  p=scanf("%d",&d) ); //En cuanto metemos una letra peta todo
    	while (p<1);
    	
    	return 0;
    }
    Si meto una letra y presiono ENTER, ya no vuelve a pedirme más veces y se queda en un bucle infinito mostrando 0 (resultado incorrecto). Pero eso no es lo que quiero, como podéis ver en el bucle.
    Me he leido la "documentacion" de scanf y pone exactamente eso, 0 si no se ha podido convertir, EOF si hay error en la entrada o >0 para cuantas se han convertido (como solo he puesto un %d, como mucho es un 1).
    Si algo tan sencillo como eso no funciona, me da que C, GCC o scanf, alguno de los tres apestan.

  7. #7
    Viciadill@
    Ubicación
    Madrid
    Mensajes
    161

    Predeterminado Re: Empezando con C .. resultados diversos

    Ocurre algo bastante lógico: cuando scanf() no encuentra en el flujo de entrada lo esperado, devuelve <=0 y deja intacto dicho flujo de entrada.

  8. #8
    Con domicilio en Noticias3d.com Avatar de Black_ice_Spain
    Ubicación
    Cantabria/BCN
    Edad
    24
    Mensajes
    6,114

    Predeterminado Re: Empezando con C .. resultados diversos

    ¿Es posible que cuando metes una letra, la letra o el salto de linea se quede "para siempre" en el flujo de entrada hasta que alguien la lea? Lo cual hace que una y otra vez intentes leer esa letra y siempre imprimas 0. Vale lo que ha dicho almanzor xD!

    Intenta con

    do{
    printf("%d", p=scanf("%d",&d) ); //En cuanto metemos una letra peta todo
    if (p==0){
    char str [80];
    scanf ("%s",str);
    }
    {while (p<1);

    o con :

    do{
    printf("%d", p=scanf("%d",&d) ); //En cuanto metemos una letra peta todo
    fflush(stdin); //(no sé si hará algo xD)
    }while (p<1);

    Es que no he usado el scanf mucho la verdad xD, aparte de las tipicas prácticas que te piden que lo uses y no le haces muchas pruebas..
    Última edición por Black_ice_Spain; 05/05/2012 a las 16:48

    GPU
    :7850 1gb@1100 CPU:I5 2500K@4.6 Placa: Asrock Z77 Pro3Memory: 8gb 1600 Sonido: Xonar DG/CAL!Monitor:BENQ BL2400PT Caja: Antec Lanboy

  9. #9

    Predeterminado Re: Empezando con C .. resultados diversos

    Vale, esas son las respuestas que esperaba.

    El truco estaba en el stdin, que parece ser que es un buffer de entrada del teclado que se queda ahí y por eso no vuelve a leer el scanf hasta que stdin no esté vacío.

    Ya que estoy, he encontrado que la solución fflush(stdin) no vale:
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351


    En cambio se tiene que hacer con fgets, por ejemplo:
    char bufferS[10];
    fgets(bufferS, sizeof(bufferS), stdin);
    printf("En stdin: %s", bufferS);

    Aunque esto en este caso solo funciona 100% bien con un tamaño máximo de 10, si que lo libera con dos pasadas si es de hasta 20.
    Se podría hacer dinámico en función de los caracteres insertados.
    Pero si lo que nos interesa es liberar todo lo del stdin, sin importar lo que metamos, podemos hacerlo tan sencillo como:

    char bufferS[5];
    fgets(bufferS, 5, stdin); //Liberará de 5 en 5 los caracteres (bytes), y luego continuará la ejecución de forma normal.

    O mejor aún, la solución 1ª propuesta por ti: char str[80]; scanf("%s", str);
    Genial!

    Gracias.

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •