Fecha de entrega: Lunes 13 de Febrero de 2017.
EOF es un acrónimo para End Of File, y es una macro (regla que especifica cómo una secuencia de entrada es mapeada a una de salida de acuerdo a un procedimiento dado) definida en la librería principal de C que tiene el valor entero -1, es decir, está definida como un entero de valor negativo. Esto es así porque las funciones de lectura de archivos regresan dicho valor al llegar al final del mismo. Debemos tener en cuenta la siguiente tabla:
Tipo | Tamaño (bytes) |
---|---|
char | 1 |
int | 4 |
Es decir, un int
contiene más información que un char
por lo que aunque a la variable c le demos un valor del tipo char
para poder hacer la comparación lógica y que se le pueda pasar la función putchar()
al igual que getchar()
que también están definidas como int
se tiene que hacer una promoción a entero. Esto puede sucede implícitamente aunque definiéramos a c como char
pero si ingresáramos un int
o algún otro tipo de variable, primero lo guardaría como char
y al hacer una conversión a int
para poder llevar a acabo la función putchar()
perdería información. Es por esta razón que lo debemos definir como un entero.
{C}
#include <stdio.h>
int main(void){
int c;
while(c != EOF){
c = getchar();
putchar(c);
}
}
Debido a que no se le da un valor inicial a la variable c entonces tiene un valor indefinido que no es igual a EOF
por esta razón comienza el bucle de la misma manera que lo haría normalmente. Dado que como se mencionó anteriormente el valor por default de la variable es nulo, sería posible poner primero la instrucción de putchar()
y después la de c = getchar()
porque imprimiría un nulo que es no imprimir nada y luego leería el stdin pero estrictamente esta práctica sería incorrecta porque la secuencia en la que queremos que se ejecuten los comando es que primero lea la entrada y luego la imprima, por lo que si lo hiciéramos al revés se estaría imprimiendo la entrada del bucle anterior.
Por ejemplo:
{bash}
$echo -e "hola\n" | ./ejecutable.out
entonces el programa imprime 4
Para lograr esa tarea basta con entender el funcionamiento de la función getchar()
, que va a revisar los caracteres que escribamos uno a uno, entonces podemos utilizar un contador para que cada vez que lo haga vaya sumando unidades hasta terminar la línea (es decir, que haya un salto de línea o \n
).
{C}
#include <stdio.h>
int main(void){
int c;
int i = 0;
while((c = getchar()) != '\n') i++;
printf("%d\n",i);
}
In [1]:
echo -e "hola\n" | ./inciso_3.out
Esto requiere una simple modificación al script anterior, pues ahora sólo vamos a terminar de leer el archivo si encontramos el valor EOF y vamos a sumar al contador en el caso de que encuentre un salto de línea. Debemos de empezar el contador en uno porque usualmente la última línea no lleva salto de línea.
{C}
#include <stdio.h>
int main(void){
int c;
int i = 1;
while((c = getchar()) != EOF){
if(c == '\n') i++;
}
printf("%d\n",i);
}
Usemos como ejemplo el siguiente archivo que contiene un haiku.
In [2]:
cat haiku.txt
In [3]:
./inciso_4.out < haiku.txt