El objetivo del diseño de los iostream
es
permitir que usted pueda mover y/o formatear carácteres
fácilmente. Ciertamente no podria ser de mucha utilidad si no
se pudiera hacer la mayoria de los formateos provistos por la
familia de funciones de printf()
en C. Es
esta sección, usted aprenderá todo sobre las funciones de
formateo de salida que estan disponibles para
iostream
, con lo que puede formatear los
bytes de la manera que usted quiera.
Las funciones de formateo en iostream pueden ser algo cunfusas al principio porque a menudo existe más de una manera de controlar el formateo: a través de funciones miembro y manipuladores. Para confundir más las cosas, una función miembro genérica pone banderas de estado para controlar el formateo, como la justificación a la derecha o izquierda, el uso de letras mayúsculas para la notación hexadecimal, para siempre usar un punto decimal para valores de coma flotante, y cosas así. En el otro lado, funciones miembro separadas activan y leen valores para el caracter de relleno, la anchura del campo, y la precisión.
En un intento de clarificar todo esto, primero examinaremos el formateo interno de los datos de un iostream, y las funciones miembro que pueden modificar estos datos. (Todo puede ser controlado por funciones miembro si se desea). Cubriremos los manipuladores aparte.
La clase ios
contiene los miembros de
datos para guardar toda la información de formateo
perteneciente a un stream
. Algunos de
estos datos tiene un rango de valores de datos y son guardados
en variables: la precisión de la coma flotante, la anchura del
campo de salida, y el carácter usado para rellenar la salida
(normalmente un espacio). El resto del formateo es determinado
por banderas, que generalmente están combinadas para ahorrar
espacio y se llaman colectivamente banderas de formateo. Puede
recuperar los valores de las banderas de formateo con la
función miembro ios::flag()
, que no toma
argumentos y retorna un objeto de tipo
fmtflags
(usualmente un sinónimo de
long
) que contiene las banderas de
formateo actuales. El resto de funciones hacen cambios en las
banderas de formateo y retornan el valor previo de las
banderas de formateo.
fmtflags ios::flags(fmtflags newflags); fmtflags ios::setf(fmtflags ored_flag); fmtflags ios::unsetf(fmtflags clear_flag); fmtflags ios::setf(fmtflags bits, fmtflags field);
La primera función fuerza que todas las banderas cambien, que a veces es lo que usted quiere. Más a menudo, usted cambia una bandera cada vez usando las otras tres funciones.
El uso de setf()
puede parecer algo confusa. Para conocer qué versión sobrecargada usar, debe conocer el
tipo de la bandera que está cambiando. Existen dos tipos de banderas: las que simplemente estan activadas o no, y aquellas que
trabajan en grupo con otras banderas. La banderas que estan encendidas/apagadas son las más simples de entender por que usted
las enciende con setf(fmtflags)
y las apaga con unsetf(fmtflags)
. Estas banderas
se muestran en la siguiente tabla:
bandera activa/inactiva
Efecto
ios::skipws
Se salta los espacios en blanco. ( Para la entrada esto es por defecto).
ios::showbase
Indica la base numérica (que puede ser, por ejemplo, decimal, octal o hexadecimal) cuando imprimimos el valor entero.
Los stream
de entrada tambié reconocen el prefijo de base cuando showbase
está
activo.
ios::showpoint
Muestra el punto decimal insertando ceros para valores de coma flotante.
ios::uppercase
Muestra A-F mayúsculas para valores hexadecimales y E para científicos.
ios::showpos
Muestra el signo de sumar (+) para los valores positivos
ios::unitbuf
'Unit buffering.' El stream
es borrado después de cada inseción.
Por ejemplo, para mostrar el signo de sumar para cout
, puede usar cout.setf(ios::showpos)
.
Para dejar de mostrar el signo de sumar, escriba cout.unsetf(ios::showpos)
.
La bandera de unitbuf
controla el almacenamiento unitario, que significa que cada inserción es lanzada a su
stream
de salida inmediatamente. Esto es útil para hacer recuento de errores, ya que en caso de fallo del
programa, sus datos son todavía escritos al fichero de log. El siguiente programa ilustra el almacenamiento unitario.
//: C04:Unitbuf.cpp {RunByHand} #include <cstdlib> // For abort() #include <fstream> using namespace std; int main() { ofstream out("log.txt"); out.setf(ios::unitbuf); out << "one" << endl; out << "two" << endl; abort(); } ///:~
Listado 5.15. C04/Unitbuf.cpp
Es necesario activar el almacenamiento unitario antes de que cualquier inserción sea hecha en el stream
.
Cuando hemos descomentado la llamada a setf()
, un compilador en particular ha escrito solo la letra 'o' en
el fichero log.txt. Con el almacenamiento unitario, ningun dato se perdió.
El stream
de salida estándar cerr
tiene el almacenamiento unitario activado por
defecto. Hay un coste para el almacenamiento unitario, asi que si un stream
de salida se usa intensivamente,
no active el almacenamiento unitario a menos que la eficiencia no sea una consideración.