Estoy frente a algo que no puedo explicar. No hay mejor manera de explicar que dando un ejemplo:
#include <stdio.h> int main () { char c; while (1) { c = getchar(); printf("%x\n", c); } return(0); }Si ejecuto este comando, itera indefinidamente de esta manera:
$ echo -n "A" | ./binary 41 ffffffff ffffffff ffffffff ffffffff ... Por lo que sé y lo que leí ( Confusión sobre cómo funciona internamente un bucle getchar() ), pensé que echo -n "A" enviaría una A a stdin y luego desencadenaría un evento EOF (no estoy seguro de qué EOF realmente is) una vez , por lo que mi ciclo iteraría dos veces como máximo, y luego dormiría esperando una nueva entrada en stdin .
Pero no, itera sobre EOF, y no entiendo por qué.
Ejecuté este comando para tratar de entender:
$ echo -n "A" | strace ./binary read(0, "A", 4096) = 1 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff6000 write(1, "41\n", 341 ) = 3 read(0, "", 4096) = 0 write(1, "ffffffff\n", 9ffffffff ) = 9 read(0, "", 4096) = 0 write(1, "ffffffff\n", 9ffffffff ) = 9 ...Entonces parece que read() no lee nada y devuelve 0, que getchar() interpreta como EOF. Pero por qué, oh, por qué itera así, mientras que cuando ejecuto este binario de la manera normal, funciona como se esperaba:
$ ./binary A 41 a B 42 a ^C $ (La salida anterior podría ser un poco confusa, pero cuando ingresé A y luego Retorno , envié A y luego \n (0x0a) a stdin, por lo que el binario solo muestra estos en sus representaciones hexadecimales, 41 y a )
Podría alguien explicarme esto ? Qué me perdí ?
Muchas gracias por leer !
Una vez que encuentre EOF , getchar regresará inmediatamente con el valor de retorno EOF . El puntero de flujo para el flujo no avanzará, permanecerá en el marcador EOF. Las llamadas subsiguientes a getchar también regresarán inmediatamente, ya que la transmisión aún se encuentra en el marcador EOF .
Tenga en cuenta que esto difiere del comportamiento cuando stdin está conectado a un dispositivo de entrada. En ese caso, getchar hará una pausa, esperando más entradas si el búfer de entrada está vacío. getchar no devolverá EOF hasta que se envíe un EOF desde el dispositivo de entrada ( CTRL-D envía EOF desde un teclado en Linux).
getchar() devuelve un int, no un char. El valor de retorno mayor le permite buscar un valor de retorno EOF, que es -1. Este es el valor devuelto para los errores y el final del archivo. Cambiar el tipo de c a int no cambiará el comportamiento de printf.
#include <stdio.h> int main () { int c; while (1) { c = getchar(); if ( c == EOF) { break; } printf("%x\n", c); } return(0); }Primero, EOF es -1, que es 0xFFFFFFFF.
la función del sistema 'getchar()' devuelve un int, no un char.
Entonces, para hacer cualquier comparación, 'c' debe ser un int, no un char.
Ahora, para salir de un ciclo while, debe haber una comparación con alguna condición que debe ser verdadera para continuar en el ciclo.
sugiera usar el siguiente modelo de código.
#include <stdio.h> int main ( void ) //<< for main, better to use 'void' rather than empty braces { int c; //<< because getchar() returns an int, not a char // following loop has EOF as exit condition // note in C, && is lower presidence than = and != so is evaluated last // note in C, && is evaluated from left to right // note to help the compiler to catch errors, // always place the literal on the left of a comparison while (c = getchar() && EOF != c) { printf("%x\n", c); } return(0); } // end function: main