Bienvenidos sean a este post, hoy veremos dos de los stream mas utilizados.
output stream
En el post anterior mencionamos que nuestros stream eran unos apuntadores de estructuras complejas de tipo FILE, y en este caso se llamaba stdout, a su vez se encarga de enviar todos los caracteres formateados mediante printf a nuestra pantalla, si bien podemos pensar que solo manda los caracteres esto no es tan asi dado que mediante esta funcion tambien podemos alterar la forma que se vera en pantalla, estos caracteres pueden ser:
- CR, Carriage Return, equivale a un Enter pero queda en la misma linea aunque a veces pasa a la siguiente linea
- NL, New Line, idem al anterior pero pasa a la linea de abajo
- VT, Vertical Tab, desplazamiento de N caracteres en vertical
- HT, Horizontal Tab, idem al anterior pero en horizontal
- BS, Backspace, se desplaza un espacio para atras
- DEL, Delete, borra un caracter
Muchos de estos fueron vistos en este post, aunque sin importar esto ultmo el flujo del stream siempre sera el mismo, la consola mostrara en pantalla el caracter o si es uno de los anteriores lo interpretara, se ubicara donde corresponde para continuar con el siguiente y asi sucesivamente, todo esto es muy bonito pero en la vida real esto trabaja de otra forma porque en realidad estos son almacenador en un buffer, es decir que son enviados a una ubicacion en memoria (un array de caracteres de tamaño fijo) antes de ser enviado a la pantalla, esto hace que el buffer junte todos los caracteres haciendo que se envien todos juntos y no uno a la vez, y su vaciamiento se puede deber a tres cosas:
- Se completo
- Se encontro una nueva linea
- Se salio del prograna
Para entender esto vamos a hacer un pequeño ejemplo, generen un archivo que llamaremos consola.c y le agregaremos el siguiente codigo:
consola.c
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("Esto se vera inmediatamente\n");
printf("Esto aparecera en 5 segundos...");
sleep(5);
printf("despues que se vacie el buffer\n");
return 0;
}
En este ejemplo no haremos nada extraordinario pero si mostraremos al buffer en accion, para ello agregaremos una nueva libreria y en este caso es unistd.h la cual nos permitira tener acceso a una funcion, nuestro pimer paso sera mostrar una linea en pantalla, despues mostraremos otra, le agregaremos a la funcion sleep, la cual generara una demora de 5 segundos para luego mostrar otra linea, observen el mensaje que pasamos en estas dos lineas, con todo esto comentado pasemos a compilarlo y ejecutarlo para ver como trabaja mediante el siguiente video
Si observan en el video, la primer linea se escribio inmediatamente despues de ejecutado pero en cambio las otras dos lineas no lo hicieron, esto es debido a que en la segunda linea no agregamos el modificador de nueva linea (\n) por lo tanto considera que no se termino de llenar el buffer, llama al sleep, genera la pausa y cuando procesa la siguiente linea al encontrar el modificador si procede a mostrar ambas lineas, a esto nos referiamos cuando hablamos de las formas de limpiar el buffer, tomen el codigo anterior y hagan algunas pruebas como agregar mas lineas o el modificador en la segunda y observen las distintas conductas que tomar este codigo.
Una ultima revision/aclaracion sobre como mostramos los datos en pantalla, hasta ahora dijimos que tenemos dos funciones que hasta son similares pero trabajan de distinta forma como son printf y fprintf, en ambos casos mostraremos los datos en pantalla pero con distitnas sintaxis, veamos cada una de ellas:
printf("literal", datos)
fprintf(salida, "literal", datos)
La diferencia principal es que en uno podemos indicar cual sera su salida pero despues es exactamente lo mismo, para entenderlo vamos a tomar el codigo anterior y modifiquemoslo de la siguiente manera:
consola.c
#include <stdio.h>
#include <unistd.h>
int main()
{
fprintf(stdout, "Esto se vera inmediatamente\n");
fprintf(stdout, "Esto aparecera en 5 segundos...");
sleep(5);
fprintf(stdout, "despues que se vacie el buffer\n");
return 0;
}
Modificamos los printf por fprintf, si lo compilan deberan obtener la misma salida e inclusive pueden hacerlo con codigos que hayamos visto en otros posts y deberia funcionar de la misma forma, y para ir finalizando con este tema les recuerdo que tanto printf, fprintf y sprintf toman los datos de una variable que esta en binario, la convierten en un string que es copiada/escrita en nuestro stream de salida, es decir que el valor 125 es formateado con %d caracter por caracter y luego es insertado en nuestro string final de salida.
input stream
Este es otro apuntador de estructura compleja de tipo FILE que sera denominado como stdin, este solo lee todos los caracteres que ingresemos desde nuestro teclado (o medio de entrada) y sera formateado por la funcion scanf, al igual que el stream anterior este tambien se «buffea», es decir que se almacenaran en un buffer y este no sera liberado hasta que se llene o reciba un CR o NL como caracter, durante ese instante la terminal o consola tendra el control y no volvera a nuestro programa hasta que el buffer haya sido liberado, el procesamiento hacia nuestro programa seria por cada caracter ingresado si trabajara de esa forma pero es un poco mas complicado porque la consola tiene dos formas de hacerlo:
- cooked mode
- raw mode
El primero utiliza buffer para la entrada, siendo esta su manera predeterminada salvo que la cambiemos, esto nos da la posibilidad de modificar el contenido del buffer antes de que sea enviado mediante el CR o NL, ya que el Backspace y Delete trabajan sobre este buffer, es decir que la consola manejara el buffer hasta que sea enviado el programa.
El segundo en cambio toma cada caracter y lo envia directamente al programa para procesarlo individualmente, el buffer en este caso es de un solo caracter y al ser tan directo no existe un procesamiento de la consola y capacidad de edicion del mismo, pero no se preocupen por esto ahora porque sera un tema que veremos mas adelante cuando hablemos sobre el scanf.
En resumen, hoy hemos visto el stream de entrada y salida, como trabajan, como se componen, las formas de trabajar, un ejemplo del buffer en el stream de salida y despues hablamos un poco sobre el stream de entrada, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
