5.3.3c1 Manipuladores estándar
§1 Introducción
Debido a que son de uso frecuente, la Librería Estándar de E/S dispone de un amplio surtido de manipuladores predefinidos para los miembros de la jerarquía.
Existen en las dos formas, comentadas en el capítulo anterior: con un argumento y sin él. Estos últimos están definidos en forma de funciones genéricas que devuelven y aceptan referencias y constituyen tres subgrupos según el tipo de estas referencias. En el primero son istreams (tipos basic_istream), en cuyo caso solo pueden aplicarse sobre flujos de entrada; sus declaraciones están en <istream>. En el segundo son ostreams (tipos basic_ostream) por lo que solo pueden aplicarse sobre flujos de salida; sus declaraciones están en <ostream>. El tercer grupo y más numeroso, lo constituyen las que utilizan iostreams (tipos ios_base) por lo que pueden utilizarse en flujos de cualquier tipo. Sus declaraciones están en <ios>.
Además de los anteriores existen seis manipuladores en forma de funciones que aceptan un argumento. Sus declaraciones están en una cabecera específica <iomanip>. Como el resto de miembros de la LE, todos ellos están definidos en el espacio std ( 4.1.11c2).
§2 Resumen
A continuación se incluye un relación de los manipuladores estándar, agrupados en función del tipo de objeto para el que están definidos. Como puede verse, salvo alguna excepción la práctica totalidad se relaciona con operaciones de formato del flujo.
La columna V.d. representa el valor devuelto. La columna efecto muestra la invocación equivalente. Dentro de la columna Declaración, el nombre del manipulador se ha resaltado en negrita. Por ejemplo:
cout << boolalpha << x;
es equivalente a:
cout.setf(ios::boolalpha); cout << x;
Declaración | Efecto | V.d. |
ios_base | ||
ios_base& boolalpha(ios_base& str); | str.setf(ios_base::boolalpha); | str |
ios_base& noboolalpha(ios_base& str); | str.unsetf(ios_base::boolalpha); | str |
ios_base& showbase(ios_base& str); | str.setf(ios_base::showbase); | str |
ios_base& noshowbase(ios_base& str); | str.unsetf(ios_base::showbase); | str |
ios_base& showpoint(ios_base& str); | str.setf(ios_base::showpoint); | str |
ios_base& noshowpoint(ios_base& str); | str.unsetf(ios_base::showpoint); | str |
ios_base& showpos(ios_base& str); | str.setf(ios_base::showpos); | str |
ios_base& noshowpos(ios_base& str); | str.unsetf(ios_base::showpos); | str |
ios_base& skipws(ios_base& str); | str.setf(ios_base::skipws); | str |
ios_base& noskipws(ios_base& str); | str.unsetf(ios_base::skipws); | str |
ios_base& uppercase(ios_base& str); | str.setf(ios_base::uppercase); | str |
ios_base& nouppercase(ios_base& str); | str.unsetf(ios_base::uppercase); | str |
ios_base& unitbuf(ios_base& str); | str.setf(ios_base::unitbuf); | str |
ios_base& nounitbuf(ios_base& str); | str.unsetf(ios_base::unitbuf); | str |
ios_base& internal(ios_base& str); | str.setf(ios_base::internal, ios_base::adjustfield); | str |
ios_base& left(ios_base& str); | str.setf(ios_base::left, ios_base::adjustfield); | str |
ios_base& right(ios_base& str); | str.setf(ios_base::right, ios_base::adjustfield); | str |
ios_base& dec(ios_base& str); | str.setf(ios_base::dec, ios_base::basefield); | str |
ios_base& hex(ios_base& str); | str.setf(ios_base::hex, ios_base::basefield); | str |
ios_base& oct(ios_base& str); | str.setf(ios_base::oct, ios_base::basefield); | str |
ios_base& fixed(ios_base& str); | str.setf(ios_base::fixed, ios_base::floatfield); | str |
ios_base& scientific(ios_base& str); | str.setf(ios_base::scientific, ios_base::floatfield); | str |
basic_ostream | ||
basic_ostream& endl(basic_ostream& os); | os.put(os.widen(’\n’) ); os.flush(); | os |
basic_ostream& ends(basic_ostream& os); | Inserta un carácter nulo en la secuencia de salida: put(charT()); | os |
basic_ostream& flush(basic_ostream& os); | os.flush(); | os |
basic_istream | ||
basic_istream& ws(basic_istream& is); | Extráe caracteres de la secuencia mientras el próximo sea un "Whitespace" ( 5.3.3b) o no existan más caracteres. En este último caso, si no existen más, se setea eofbit pero no failbit ( 5.3.2a) | is |
<iomanip> | Los manipuladores que siguen son funciones genéricas (plantillas) que reciben argumentos de distintos tipos [1]. | |
sm resetiosflags(ios_base::fmtflags mask); | Limpia todos
los bits de fmtflags (
5.3.2a). A continuación setea los valores en concordancia con la máscara utilizada
como argumento io.setf( (ios_base::fmtflags)0, mask); |
sm |
sm setiosflags(ios_base::fmtflags mask); | Establece el valor de la mascara de formato fmtflags ( 5.3.2a) en concordancia con el valor pasado como argumento. io.setf(mask) | sm |
sm setbase(int base); | Establece el valor oct, dec o hex de fmtflags ( 5.3.2a) según el valor 8, 10 o 16 del argumento base. | sm |
sm setfill(char_type c); | Establece el carácter a utilizar como relleno en los procesos de ajuste del ancho del campo ( 5.3.2b) io.fill(c); | sm |
sm setprecision(int n); | Establece la precisión en los valores fraccionarios ( 5.3.2a) io.precision(n); | sm |
sm setw(int n); | Establece el ancho mínimo del campo ( 5.3.2a). io.width(n) | sm |
§3 Ejemplo
Como ejemplo, incluimos el código de una aplicación que acepta la introdución de cualquier secuencia de caracteres por el teclado, hasta que se pulsa la tecla ESC. A continuación, compone una cadena con los caracteres introducidos, precedida por una cabecera ("preamble") consistente en la longitud -en hexadecimal- de la cadena introducida en longitud constante y rellenando los espacios sobrantes con un carácter determinado.
#include <iostream>
#include <conio.h>
#include <iomanip>
#include <sstream>
#define HEADER_LEN 8
#define FILL_CHAR '-'
int main() {
std::stringstream strStream;
char c = '\0';
while (true) {
c = _getch();
if (c == 27) break;
strStream << c;
std::cout << c;
}
std::stringstream headed_stream;
headed_stream << std::setw(HEADER_LEN) << std::setfill(FILL_CHAR)
<< std::hex << strStream.str().length();
std::cout << "\n" << headed_stream.str() << strStream.str() << std::endl;
std::cout << "\nPress Enter to exit..." << std::endl;
std::cin.get();
return 0;
}
Como puede verse, aparte de la introducción de datos y la pausa en la salida para comprobar el resultado, el código no requiere ulterior explicación, solo señalar que el trabajo se realiza en un par de líneas. Incluimos una posible salida junto con los datos proporcionados.
Realmente se trata de un lenguaje complicado
------2cRealmente se trata de un lenguaje complicado
Press Enter to exit....
El código que sigue muestra cómo podríamos obtener en una variable la longitud a partir del flujo anterior, suponiendo que la secuencia contiviera un valor hexadecimal válido (posiblemente sustituyendo los caracteres '-' del preámbulo por espacios).
int streamLen = 0;
headed_stream >> std::setw(HEADER_LEN) >> std::hex >> streamLen;
std::cout << "Stream length = " << streamLen << " characters" << std::endl;
[1] El tipo señalado sm depende de la implementación y puede ser diferente para cada función.