Veremos ahora algunas de las funciones que forman parte de las principales clases relacionadas con los streams.
No es necesario estudiar en profundidad estas clases, puede usarse este capítulo como consulta para el uso de streams. Con la práctica se aprende a usar las funciones necesarias en cada caso.
Es la clase base para todas las clases con buffer, proporciona el interfaz entre los datos y las áreas de almacenamiento como la memoria o los dispositivos físicos.
Si las aplicaciones necesitan acceder al buffer de un stream, lo hacen a través del puntero almacenado en la clase ios. Pero normalmente el acceso se hace a alto nivel, directamente desde funciones de ios y sus clases derivadas, y casi nunca directamente a través de streambuf.
Por eso veremos muy pocas funciones de la clase streambuf, ya que la mayoría tienen escasa utilidad en programación normal.
Por otra parte, he consultado bastante documentación al respecto de las estructuras de las clases, y varias implementaciones de distintos compiladores, y no parece existir gran unanimidad al respecto de las funciones que deben incluir ciertas clases. El caso de streambuf es de los más heterogéneos, de modo que sólo incluiré algunas de las funciones más frecuentes.
int allocate();
Prepara el área del buffer.
char *base();
Devuelve la dirección de comienzo del área del buffer.
int blen();
Devuelve la longitud del área del buffer.
void unbuffered(int); int unbuffered();
La primera forma modifica el estado del buffer, la segunda devuelve un valor no nulo si no está activado el buffer.
int in_avail();
Devuelve el número de caracteres que permanecen en el buffer de entrada interno disponibles para su lectura.
int out_waiting();
Devuelve el número de caracteres que permanecen en el buffer interno de salida.
virtual streampos seekoff(streamoff offset, ios::seek_dir, int mode);
Cambia la posición relativa del puntero del fichero desde el punto definido por seek_dir, el valor de offset.
Para seek_dir se usan los valores definidos en el enum de la clase ios:
Valor |
Significado |
ios::beg | Desplazamiento desde el principio del fichero |
ios::cur | Desplazamiento desde la posición actual del puntero |
ios::end | Desplazamiento desde el final del fichero |
El valor de offset puede ser positivo o negativo, si es negativo, el desplazamiento es en la dirección del principio del fichero.
El parámetro mode especifica que el movimiento puede ser en el área de entrada, salida o ambos, especificado por ios::in, ios::out o los dos.
Se trata de una función virtual, cuando se redefine en clases derivadas, puede funcionar con respecto al stream, y no sobre el buffer interno de streambuf:
virtual streampos seekpos(streampos, int = (ios::in | ios::out));
Cambia o lee la posición del puntero del buffer interno de streambuf a una posición absoluta streampos.
También es una función virtual, de modo que puede ser redefinida en clases derivadas para modificar la posición en un stream de entrada o salida.
streambuf* setbuf(unsigned char*, int);
Especifica el array para ser usado como buffer interno.
int sgetc();
Toma el siguiente carácter del buffer interno de entrada.
int sgetn(char*, int n);
Toma los siguientes n caracteres del buffer interno de entrada.
int snextc();
Avanza y toma el siguiente carácter del buffer interno de entrada.
int sputbackc(char);
Devuelve un carácter al buffer de entrada interno.
int sputc(int);
Coloca un carácter en el buffer de salida interno.
int sputn(const char*, int n);
Coloca n caracteres en el buffer de salida interno.
void stossc();
Avanza al siguiente carácter en el buffer de entrada interno
La clase ios está diseñada para ser la clase base de otras clases derivadas como istream, ostream, iostream, fstreambase y strstreambase. Proporciona operaciones comunes de entrada y salida
Dentro de la clase ios se definen varios tipos enumerados que son útiles para modificar flags y opciones o para el tratamiento de errores o estados de un stream.
Todos los miembros de enums definidos en la clase ios son accesibles mediante el operador de ámbito. Por ejemplo:
ios::eofbit ios::in ios::beg ios::uppercase
enum io_state { goodbit, eofbit, failbit, badbit };
enum open_mode { in, out, ate, app, trunc, nocreate, noreplace, binary };
enum seek_dir { beg, cur, end};
enum { skipws, left, right, internal, dec, oct, hex, showbase, showpoint, uppercase, showpos, scientific, fixed, unitbuf, stdio };
Permiten trabajar con grupos de modificadores afines.
enum { basefield=dec+oct+hex, floatfield = scientific+fixed, adjustfield = left+right+internal };
No nos interesan todas las funciones de las clases que vamos a estudiar, algunas de ellas raramente las usaremos, y en general son de poca o ninguna utilidad.
int bad();
Devuelve un valor distinto de cero si ha ocurrido un error.
Sólo se comprueba el bit de estado ios::badbit, de modo que esta función no equivale a !good().
void clear(iostate state=0);
Sirve para modificar los bits de estado de un stream, normalmente para eliminar un estado de error. Se suelen usar constantes definidas en el enum io_state definido en ios, usando el operador de bits OR para modificar varios bits a la vez.
int eof();
Devuelve un valor distinto de cero si se ha alcanzado el fin de fichero.
Esta función únicamente comprueba el bit de estado ios::eofbit.
int fail();
Devuelve un valor distinto de cero si una operación sobre el stream ha fallado.
Comprueba los bits de estado ios::badbit y ios::failbit.
Cambia el carácter de relleno que se usa cuando la salida es más ancha de la necesaria para el dato actual.
int fill(); int fill(char);
La primera forma devuelve el valor actual del carácter de relleno, la segunda permite cambiar el carácter de relleno para las siguientes salidas, y también devuelve el valor actual.
Ejemplo:
int x = 23; cout << "|"; cout.width(10); cout.fill('%'); cout << x << "|" << x << "|" << endl;
Permite cambiar o leer los flags de manipulación de formato.
long flags () const;
long flags (long valor);
La primera forma devuelve el valor actual de los flags.
La segunda cambia el valor actual por valor, el valor de retorno es el valor previo de los flags.
Ejemplo:
int x = 235; long f; cout << "|"; f = flags(); f &= !(ios::adjustfield); f |= ios::left; cout.flags(f); cout.width(10); cout << x << "|" << endl;
int good();
Devuelve un valor distinto de cero si no ha ocurrido ningún error, es decir, si ninguno de los bits de estado está activo.
Aunque pudiera parecerlos, esta función no es exactamente equivalente a !bad().
En realidad es equivalente a rdstate() == 0.
Permite cambiar el número de caracteres significativos que se mostrarán cuando trabajemos con números en coma flotante: float o double.
int precision(); int precision(char);
La primera forma devuelve el valor actual de la precisión, la segunda permite modificar la precisión para las siguientes salidas, y también devuelve el valor actual.
float x = 23.45684875; cout << "|"; cout.precision(6); cout << x << "|" << x << "|" << endl;
streambuf* rdbuf();
Devuelve un puntero al streambuf asignado a este stream.
int rdstate();
Devuelve el estado del stream. Este estado puede ser una combinación de cualquiera de los bits de estado definidos en el enum ios::io_state, es decir ios::badbit, ios::eofbit, ios::failbit e ios::goodbit. El goodbit no es en realidad un bit, sino la ausencia de todos los demás. De modo que para verificar que el valor obtenido por rdstate es ios::goodbit tan sólo hay que comparar. En cualquier caso es mejor usar la función good().
En cuanto a los restantes bits de estado se puede usar el operador & para verificar la presencia de cada uno de los bits. Aunque de nuevo, es preferible usar las funciones bad(), eof() o fail().
Permite modificar los flags de manipulación de formato.
long setf(long); long setf(long valor, long mascara);
La primera forma activa los flags que estén activos tanto en el parámetro y deja sin cambios el resto.
La segunda forma activa los flags que estén activos tanto en valor como en máscara y desactiva los que estén activos en mask, pero no en valor. Podemos considerar que mask contiene activos los flags que queremos modificar y valor los flags que queremos activar.
Ambos devuelven el valor previo de los flags.
int x = 235; cout << "|"; cout.setf(ios::left, ios::left | ios::right | ios::internal); cout.width(10); cout << x << "|" << endl;
Algunos streams de entrada están enlazados a otros. Cuando un stream de entrada tiene caracteres que deben ser leídos, o un stream de salida necesita más caracteres, el buffer del fichero enlazado se vacía automáticamente.
Por defecto, cin, err y clog están enlazados con cout. Cuando se usa cin, el buffer de cout se vacía automáticamente.
ostream* tie(); ostream* tie(ostream* val);
La primera forma devuelve el stream (enlazado), o cero si no existe. La segunda enlaza otro stream al actual y devuelve el previo, si existía.
Permite eliminar flags de manipulación de formato:
void unsetf(long mascara);
Desactiva los flags que estén activos en el parámetro.
Nota: en algunos compiladores he comprobado que esta función tiene como valor de retorno el valor previo de los flags.
int x = 235; cout << "|"; cout.unsetf(ios::left | ios::right | ios::internal); cout.setf(ios::left); cout.width(10); cout << x << "|" << endl;
Cambia la anchura en caracteres de la siguiente salida de stream:
int width(); int width(int);
La primera forma devuelve el valor de la anchura actual, la segunda permite cambiar la anchura para las siguientes salidas, y también devuelve el valor actual de la anchura.
int x = 23; cout << "#"; cout.width(10); cout << x << "#" << x << "#" << endl;
static int xalloc();
Devuelve un índice del array de las palabras no usadas que pueden ser utilizadas como flags de formatos definidos por el usuario.
void init(streambuf *);
Asocia el objeto de la clase ios con el streambuf especificado.
void setstate(int);
Activa los bits de estado seleccionados. El resto de los bits de estado no se ven afectados, si llamamos a setstate(ios::eofbit), se añadirá ese bit, pero no se eliminarán los bits ios::badbit o ios::failbit si ya estaban activos.
© Noviembre de 2001 Salvador Pozo, salvador@conclase.net