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.

Clase streambuf

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.

Funciones protegidas

Función allocate (no siempre disponible)

int allocate();

Prepara el área del buffer.

Función base (no siempre disponible)

char *base();

Devuelve la dirección de comienzo del área del buffer.

Función blen (no siempre disponible)

int blen();

Devuelve la longitud del área del buffer.

Función unbuffered (no siempre disponible)

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.

Funciones publicas

Función in_avail

int in_avail();

Devuelve el número de caracteres que permanecen en el buffer de entrada interno disponibles para su lectura.

Función out_waiting

int out_waiting();

Devuelve el número de caracteres que permanecen en el buffer interno de salida.

Función seekoff

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:

Función seekpos

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.

Función setbuf

streambuf* setbuf(unsigned char*, int);

Especifica el array para ser usado como buffer interno.

Función sgetc

int sgetc();

Toma el siguiente carácter del buffer interno de entrada.

Función sgetn

int sgetn(char*, int n);

Toma los siguientes n caracteres del buffer interno de entrada.

Función snextc

int snextc();

Avanza y toma el siguiente carácter del buffer interno de entrada.

Función sputbackc

int sputbackc(char);

Devuelve un carácter al buffer de entrada interno.

Función sputc

int sputc(int);

Coloca un carácter en el buffer de salida interno.

Función sputn

int sputn(const char*, int n);

Coloca n caracteres en el buffer de salida interno.

Función stossc

void stossc();

Avanza al siguiente carácter en el buffer de entrada interno.

Clase ios

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

Enums

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

io_state

enum io_state ; 

open_mode

enum open_mode { in, out, ate, app, trunc, nocreate, 
   noreplace, binary };

seek_dir

enum seek_dir ; 

Flags de modificadores de formato

enum { skipws, left, right, internal, 
   dec, oct, hex, showbase, showpoint, 
   uppercase, showpos, scientific, 
   fixed, unitbuf, stdio };

Máscaras de modificadores

Permiten trabajar con grupos de modificadores afines.

enum { 
   basefield = dec+oct+hex, 
   floatfield = scientific+fixed, 
   adjustfield = left+right+internal 
};

Funciones

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.

Función bad

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().

Función clear

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.

Función eof

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.

Función fail

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.

Función fill

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;

Función flags

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;

Función good

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 parecerlo, (good significa bueno y bad malo, en inglés) esta función no es exactamente equivalente a !bad().

En realidad es equivalente a rdstate() == 0.

Función precision

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;

Función rdbuf

streambuf* rdbuf();

Devuelve un puntero al streambuf asignado a este stream.

Función rdstate

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().

Función setf

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;

Función tie

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.

Función unsetf

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;

Función width

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; 

Función xalloc

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.

Función init (protegida)

void init(streambuf *);

Asocia el objeto de la clase ios con el streambuf especificado.

Función setstate (protegida)

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.