Apéndice E Streams
Las operaciones de entrada y salida nunca formaron parte de C ni tampoco lo forman de C++. En ambos lenguajes, todas las operaciones de entrada y salida se hacen mediante bibliotecas externas.
En el caso de C, esa biblioteca es stdio, que agrupa todas las funciones de entrada y salida desde teclado, pantalla y ficheros de disco. En el caso de C++ se dispone de varias clases: streambuf, ios, istream, ostream y fstream.
Dejar fuera del lenguaje todas las operaciones de entrada y salida tiene varias ventajas:
- Independencia de la plataforma: cada compilador dispone de diferentes versiones de cada biblioteca para cada plataforma. Tan sólo se cambia la definición de las clases y bibliotecas, pero la estructura, parámetros y valores de retorno son iguales. Los mismos programas, compilados para diferentes plataformas funcionan del mismo modo.
- Encapsulación: para el programa todos los dispositivos son de entrada y salida se tratan del mismo modo, es indiferente usar la pantalla, el teclado o ficheros.
- Buffering: el acceso a dispositivos físicos es lento, en comparación con el acceso a memoria. Las operaciones de lectura y escritura se agrupan, haciéndolas en memoria, y las operaciones físicas se hacen por grupos o bloques, lo cual ahorra mucho tiempo.
Clases predefinidas para streams
Un stream es una abstracción para referirse a cualquier flujo de datos entre una fuente y un destinatario. Los streams se encargan de convertir cualquier tipo de objeto a texto legible por el usuario, y viceversa. Pero no se limitan a eso, también pueden hacer manipulaciones binarias de los objetos y cambiar la apariencia y el formato en que se muestra la salida.
C++ declara varias clases estándar para el manejo de streams:
- streambuf: manipulación de buffers.
- ios: entradas y salidas, incluye en su definición un objeto de la clase streambuf.
- istream: derivada de ios, clase especializada en entradas.
- ostream: derivada de ios, clase especializada en salidas.
- iostream: derivada de istream y ostream, se encarga de encapsular las funciones de entrada y salida por teclado y pantalla.
- fstream: entrada y salida desde ficheros.
Las clases base son streambuf e ios, las demás se derivan de estas dos.
La clase streambuf proporciona un interfaz entre la memoria y los dispositivos físicos.
La clase ios contiene además un puntero a un objeto de la clase streambuf. Proporciona soporte para entradas y salidas con validación y formato usando un streambuf.
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 públicas
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 { goodbit, eofbit, failbit, badbit };
open_mode
enum open_mode { in, out, ate, app, trunc, nocreate, noreplace, binary };
seek_dir
enum seek_dir { beg, cur, end };
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.
Clase filebuf
La declaración de esta clase está en el fichero fstream.
Esta clase se base en la clase streambuf, y le proporciona las funciones necesarias para manipular entrada y salida de caracteres en ficheros.
Las funciones de entrada y salida de istream y ostream hacen llamadas a funciones de filebuf, mediante el puntero a filebuf que existe en la clase ios.
Constructores
filebuf::filebuf(); filebuf::filebuf(int fd); filebuf::filebuf(int fd, char *, int n);
La primera forma crea un filebuf que no está asociado a ningún fichero.
La segunda forma crea un filebuf asociado a un fichero mediante el descriptor fd.
La tercera forma crea un filebuf asociado a un fichero especificado mediante el descriptor fd y asociado a un buffer buf de tamaño n bytes. Si n es cero o negativo, el filebuf es sin buffer.
Nota:
He comprobado que algunos compiladores sólo disponen de la primera versión del constructor.
Funciones
Función attach (no siempre disponible)
filebuf* attach(int fd);
El filebuf debe estar cerrado, esta función asocia el filebuf a otro fichero especificado mediante el descriptor fd.
Función close
filebuf* close();
Actualiza la información actualmente en el buffer y cierra el fichero. En caso de error, retorna el valor 0.
Función fd (no siempre disponible)
int fd();
Devuelve el descriptor de fichero o EOF.
Función is_open
int is_open();
Si el fichero está abierto devuelve un valor distinto de cero.
Función open
filebuf* open(const char *name, int mode, int prot = filebuf::openprot);
Abre un fichero para un objeto de una clase específica, con el nombre name. Para el parámetro mode se puede usar el enum open_mode definido en la clase ios.
Parámetro mode | Efecto |
---|---|
ios::app | (append) Se coloca al final del fichero antes de cada operación de escritura. |
ios::ate | (at end) Se coloca al final del stream al abrir el fichero. |
ios::binary | Trata el stream como binario, no como texto. |
ios::in | Permite operaciones de entrada en un stream. |
ios::out | Permite operaciones de salida en un stream. |
ios::trunc | (truncate) Trunca el fichero a cero al abrirlo. |
El parámetro prot se corresponde con el permiso de acceso DOS y es usado siempre que no se indique el modo ios::nocreate. Por defecto se usa el permiso para leer y escribir. En algunas versiones de las bibliotecas de streams no existe este parámetro, ya que está íntimamente asociado al sistema operativo.
Función overflow
virtual int overflow(int = EOF);
Vacía un buffer a su destino. Todas las clases derivadas deben definir las acciones necesarias a realizar.
Función seekoff
virtual streampos seekoff(streamoff offset, ios::seek_dir, int mode);
Mueve el cursor del fichero a una posición relativa offset a la posición actual en la dirección indicada por seek_dir.
Para seek_dir se usan los valores definidos en el enum seek_dir 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 |
Cuando se especifica un valor negativo como desplazamiento, éste se hace en la dirección del comienzo del fichero desde la posición actual o desde el final del fichero.
El parámetro mode indica el tipo de movimiento en el área de entrada o salida del buffer interno mediante los valores ios::in, ios::out o ambos.
Cuando esta función virtual se redefine en una clase derivada, debe desplazarse en el stream, y no en el buffer del miembro streambuffer interno.
Función setbuf
virtual streambuf* setbuf(char*, int);
Especifica un buffer del tamaño indicado para el objeto. Cuando se usa como un strstreambuf y la función se sobrecarga, el primer argumento no tiene sentido, y debe ponerse a cero.
Función sync
virtual int sync();
Sincroniza las estructuras de datos internas y externas del stream.
Función underflow
virtual int underflow();
Hace que la entrada esté disponible. Se llama a esta función cuando no hay más datos disponibles en el buffer de entrada. Todas las clases derivadas deben definir las acciones a realizar.
Clase istream
La declaración de esta clase está en el fichero iostream.h.
Proporciona entrada con y sin formato desde una clase derivada de streambuf via ios::bp.
El operador >> está sobrecargado para todos los tipos fundamentales, y puede formatear los datos.
La clase istream proporciona el código genérico para formatear los datos después de que son extraídos desde el stream de entrada.
Constructor
istream(streambuf *);
Asocia una clase derivada dada de streambuf a la clase que proporciona un stream de entrada. Esto se hace asignando ios::bp al parámetro del constructor.
Función rdbuf (protegida)
void eatwhite();
Extrae espacios en blanco consecutivos.
Función gcount
int gcount();
Devuelve el número de caracteres sin formato de la última lectura. Las lecturas sin formato son las realizadas mediante las funciones get, getline y read.
Función get
int get(); istream& get(char*, int len, char = '\n'); istream& get(char&); istream& get(streambuf&, char = '\n');
La primera forma extrae el siguiente carácter o EOF si no hay disponible ninguno.
La segunda forma extrae caracteres en la dirección proporcionada en el parámetro char* hasta que se recibe el delimitador del tercer parámetro, el fin de fichero o hasta que se leen len-1 bytes. Siempre se añade un carácter nulo de terminación en la cadena de salida. El delimitador no se extrae desde el stream de entrada. La función sólo falla si no se extraen caracteres.
La tercera forma extrae un único carácter en la referencia a char proporcionada.
La cuarta forma extrae caracteres en el streambuf especificado hasta que se encuentra el delimitador.
Función getline
istream& getline(char*, int, char = '\n');
Extrae caracteres hasta que se encuentra el delimitador y los coloca en el buffer, elimina el delimitador del stream de entrada y no lo añade al buffer.
Función ignore
istream& ignore(int n = 1, int delim = EOF);
Hace que los siguientes n caracteres en el stream de entrada sean ignorados; la extracción se detiene antes si se encuentra el delimitador delim.
El delimitador también es extraído del stream.
Función ipfx
istream& ipfx(int n = 0);
Esta función es previamente llamada por las funciones de entrada para leer desde un stream de entrada. Las funciones que realizan entradas con formato la llaman como ipfx(0); las que realizan entradas sin formato la llaman como ipfx(1).
Función peek
int peek();
Devuelve el siguiente carácter sin extraerlo del stream.
Función putback
istream& putback(char);
Devuelve un carácter al stream.
Función read
istream& read(char*, int);
Extrae el número indicado de caracteres en el array char*. Se puede usar la función gcount() para saber el número de caracteres extraídos si ocurre algún error.
Función seekg
istream& seekg(streampos pos); istream& seekg(streamoff offset, seek_dir dir);
La primera forma se mueve a posición absoluta, tal como la proporciona la función tellg.
La segunda forma se mueve un número offset de bytes la posición del cursor del stream relativa a dir. Este parámetro puede tomar los valores definidos en el enum seek_dir: {beg, cur, end};
Para streams de salida usar ostream::seekp.
Usar seekpos o seekoff para moverse en un buffer de un stream.
Función tellg
long tellg();
Devuelve la posición actual del stream.
Clase ostream
La declaración de esta clase está en el fichero iostream.h.
Proporciona salida con y sin formato a un streambuf.
Un objeto de la clase ostream no producirá la salida actual, pero sus funciones miembro pueden llamar a las funciones miembro de la clase apuntada por bp para insertar caracteres en el stream de salida.
El operador << da formato a los datos antes de enviarlos a bp.
La clase ostream proporciona el código genérico para formatear los datos antes de que sean insertados en el stream de salida.
Constructor
ostream(streambuf *buf);
Asocia el streambuf dado a la clase, proporcionando un stream de salida. Esto se hace asignando el puntero ios::bp a buf.
Función flush
ostream& flush();
Vacía el buffer asociado al stream. Procesa todas las salidas pendientes.
Función opfx
int opfx();
Esta función es llamada por funciones de salida para antes de hacer una inserción en un stream de salida. Devuelve cero si el ostream tiene un estado de error distinto de cero. En caso contrario, opfx devuelve un valor distinto de cero.
Función osfx
void osfx();
Realiza operaciones de salida (post?). Si está activado ios::unitbuf, osfx vacía el buffer de ostream. En caso de error, osfx activa el flag ios::failbit.
Función put
ostream& put(char ch);
Inserta un carácter en el stream de salida.
Función seekp
ostream& seekp(streampos); ostream& seekp(streamoff, seek_dir);
La primera forma mueve el cursor del stream a una posición absoluta, tal como la devuelve la función tellp.
La segunda forma mueve el cursor a una posición relativa desde el punto indicado mediante el parámetro seek_dir, que puede tomar los valores del enum seek_dir: beg, cur, end.
Función tellp
streampos tellp();
Devuelve la posición absoluta del cursor del stream.
Función write
ostream& write(const char*, int n);
Inserta n caracteres (aunque sean nulos) en el stream de salida.
Clase iostream
La declaración de esta clase está en el fichero iostream.h.
Esta clase está derivada de istream y ostream, es una mezcla de sus clases base, y permite realizar tanto entradas como salidas en un stream. Además es la base para otras clases como fstream y strstream.
El stream se implementa mediante la clase ios::bp a la que apunta. Dependiendo del tipo de clase derivada a la que apunta bp, se determina si los streams de entrada y salida pueden ser el mismo.
Por ejemplo, si iostream usa un filebuf podrá hacer entradas y salidas en el mismo fichero. Si iostream usa un strstreambuf podrá hacer entradas y salidas en la misma o en diferentes zonas de memoria.
Constructor
iostream(streambuf *);
Asocia el streambuf dado a la clase.
Clase fstreambase
La declaración de esta clase está en el fichero fstream.
Esta clase proporciona acceso a funciones de filebuf inaccesibles a través de ios::bp tanto para fstreambase como para sus clases derivadas.
La una función miembro de filebuf no en un miembro virtual de la clase base filebuf (streambuf), ésta no será accesible. Por ejemplo: attach, open y close no lo son.
Los constructores de fstreambase inicializan el dato ios::bp para que apunte al filebuf.
Constructores
fstreambase(); fstreambase(const char *name, int mode, int = filebuf::openprot); fstreambase(int fd); fstreambase(int fd, char *buf, int len);
La primera forma crea un fstreambase que no está asociando a ningún fichero.
La segunda forma crea un fstreambase, abre el fichero especificado por name en el modo especificado por mode y lo conecta a ese fichero.
La tercera forma crea un fstreambase y lo conecta a un descriptor de fichero abierto y especificado por fd.
La cuarta forma crea un fstreambase y lo conecta a un descriptor de fichero abierto especificado por fd y usando un buffer especificado por buf con el tamaño indicado por len.
Función attach
void attach(int);
Conecta con un descriptor de fichero abierto.
Función close
void close();
Cierra el filebuf y el fichero asociados.
Función open
void open(const char *name, int mode, int prot=filebuf::openprot);
Abre un fichero para el objeto especificado.
Para el parámetro mode se pueden usar los valores del enum open_mode definidos en la clase ios.
Clase | Parámetro mode |
---|---|
fstream | ios::in |
ofstream | ios::out |
El parámetro prot se corresponde con el permiso de acceso DOS, y se usa salvo que se use el valor ios::nocreate para el parámetro mode. Por defecto se usa el valor de permiso de lectura y escritura.
Función rdbuf
filebuf* rdbuf();
Devuelve el buffer usado.
Función setbuf
void setbuf(char*, int);
Asigna un buffer especificado por el usuario al filebuf.
Clase ifstream
La declaración de esta clase está en el fichero fstream.h.
Proporciona un stream de entrada para leer desde un fichero usando un filebuf.
Constructores
ifstream(); ifstream(const char *name, int mode = ios::in, int = filebuf::openprot); ifstream(int fd); ifstream(int fd, char *buf, int buf_len);
La primera forma crea un ifstream que no está asociando a ningún fichero.
La segunda forma crea un ifstream, abre un fichero de entrada en modo protegido y se conecta a él. El contenido del fichero, si existe, se conserva; los nuevos datos escritos se añaden al final. Por defecto, el fichero no se crea si no existe.
La tercera forma crea un ifstream, y lo conecta a un descriptor de un fichero fd abierto previamente.
La cuarta forma crea un ifstream conectado a un fichero abierto especificado mediante su descriptor, fd. El ifstream usa el buffer especificado por buf de longitud buf_len.
Función open
void open(const char *name, int mode, int prot=filebuf::openprot);
Abre un fichero para el objeto especificado.
Para el parámetro mode se pueden usar los valores del enum open_mode definidos en la clase ios.
Clase | Parámetro mode |
---|---|
fstream | ios::in |
ofstream | ios::out |
El parámetro prot se corresponde con el permiso de acceso DOS, y se usa salvo que se use el valor ios::nocreate para el parámetro mode. Por defecto se usa el valor de permiso de lectura y escritura.
Función rdbuf
filebuf* rdbuf();
Devuelve el buffer usado.
Clase ofstream
La declaración de esta clase está en el fichero fstream.
Proporciona un stream de salida para escribir a un fichero usando un filebuf.
Constructores
ofstream(); ofstream(const char *name, int mode = ios::out, int = filebuf::openprot); ofstream(int fd); ofstream(int fd, char *buf, int buf_len);
La primera forma crea un ofstream que no está asociando a ningún fichero.
La segunda forma crea un ofstream, abre un fichero de salida y se conecta a él.
La tercera forma crea un ofstream, y lo conecta a un descriptor de un fichero fd abierto previamente.
La cuarta forma crea un ofstream conectado a un fichero abierto especificado mediante su descriptor, fd. El ofstream usa el buffer especificado por buf de longitud buf_len.
Función open
void open(const char *name, int mode, int prot=filebuf::openprot);
Abre un fichero para el objeto especificado.
Para el parámetro mode se pueden usar los valores del enum open_mode definidos en la clase ios.
Clase | Parámetro mode |
---|---|
fstream | ios::in |
ofstream | ios::out |
El parámetro prot se corresponde con el permiso de acceso DOS, y se usa salvo que se use el valor ios::nocreate para el parámetro mode. Por defecto se usa el valor de permiso de lectura y escritura.
Función rdbuf
filebuf* rdbuf();
Devuelve el buffer usado.
Clase fstream
La declaración de esta clase está en el fichero fstream.h.
Proporciona un stream de salida y salida a un fichero usando un filebuf.
La entrada y la salida se inicializan usando las funciones de las clases base istream y ostream. Por ejemplo, fstream puede usar la función istream::getline() para extraer caracteres desde un fichero.
Constructores
fstream(); fstream(const char *name, int mode = ios::in, int = filebuf::openprot); fstream(int fd); fstream(int fd, char *buf, int buf_len);
La primera forma crea un fstream que no está asociando a ningún fichero.
La segunda forma crea un fstream, abre un fichero con el acceso especificado por mode y se conecta a él.
La tercera forma crea un fstream, y lo conecta a un descriptor de un fichero fd abierto previamente.
La cuarta forma crea un fstream conectado a un fichero abierto especificado mediante su descriptor, fd. El fstream usa el buffer especificado por buf de longitud buf_len. Si buf es NULL o n no es positivo, el fstream será sin buffer.
Función open
void open(const char *name, int mode, int prot=filebuf::openprot);
Abre un fichero para el objeto especificado.
Para el parámetro mode se pueden usar los valores del enum open_mode definidos en la clase ios.
Clase | Parámetro mode |
---|---|
fstream | ios::in |
ofstream | ios::out |
El parámetro prot se corresponde con el permiso de acceso DOS, y se usa salvo que se use el valor ios::nocreate para el parámetro mode. Por defecto se usa el valor de permiso de lectura y escritura.
Función rdbuf
filebuf* rdbuf();
Devuelve el buffer usado.
Clase strstreambuf
La declaración de esta clase está en el fichero strstrea.h.
Clase base para especializar la clase ios para el manejo de streams de cadenas, esto se consigue inicializando ios::bp de modo que apunte a un objeto strstreambuf. Esto proporciona las comprobaciones necesarias para cualquier operación de entrada y salida de cadenas en memoria. Por ese motivo, la clase strstreambase está protegida y sólo es accesible para clases derivadas que realicen entradas y salidas.
Constructores
strstreambase(); strstreambase(const char*, int, char *start);
La primera forma crea un strstreambase con el buffer de su dato streambuf en memoria dinámica reservada la primera vez que se usa. Las zonas de lectura y escritura son la misma.
La segunda forma crea un strstreambase con el buffer y la posición de comienzo especificados.
Función rdbuf
strstreambuf * rdbuf();
Devuelve un puntero a strstreambuf asociado con este objeto.
Clase strstreambase
La declaración de esta clase está en el fichero strstrea.h.
Especialización de la clase ios para streams de cadena inicializando ios::bp para que apunte a un strstreambuf. Esto proporciona la condición necesaria para cualquier operación de entrada/salida en memoria. Por esa razón, strstreambase está diseñada completamente protegida y accesible sólo para clases derivadas que realicen entradas y salidas. Hace uso virtual de la clase ios.
Constructores
strstreambase(); strstreambase(const char*, int, char *start);
La primera forma crea un strstreambase con el buffer de streambuf creado dinámicamente la primera vez que se usa. Las áreas de lectura y escritura son la misma.
La segunda forma crea un strstreambase con el buffer especificado y al posición de comienzo start.
Función rdbuf
strstreambuf* rdbuf();
Devuelve un puntero al strstreambuf asociado con este objeto.
Clase istrstream
La declaración de esta clase está en el fichero strstrea.
Proporciona las operaciones de entrada en un strstreambuf.
El bloque formado por ios, istream, ostream, iostream y streambuf, proporciona una base para especializar clases que trabajen con memoria.
Constructores
istrstream(char *); istrstream(char *str, int n);
La primera forma crea un istrstream con la cadena especificada (el carácter nulo nunca se extrae).
La segunda forma crea un istrstream usando n bytes para str.
Clase ostrfstream
La declaración de esta clase está en el fichero strstrea.h.
Proporciona un stream de salida para inserción desde un array usando un strstreambuf.
Constructores
ostrstream(); ostrstream(char *buf, int len, int mode = ios::out);
La primera forma crea un ostrstream con un array dinámico como stream de entrada.
La segunda forma crea un ostrstream con un buffer especificado por buf y un tamaño especificado por len. Si mode es ios::app o ios::ate, los punteros de lectura/escritura se colocan en la posición del carácter nulo de la cadena.
Función pcount
int pcount();
Devuelve el número de caracteres actualmente almacenados en el buffer.
Función str
char *str();
Devuelve y bloquea el buffer. El usuario debe liberar el buffer si es dinámico.
Clase strstream
La declaración de esta clase está en el fichero strstrea.h.
Proporciona entrada y salida simultanea en un array usando un strstreambuf. La entrada y la salida son realizadas usando las funciones de las clases base istream y ostream.
Por ejemplo, strstream puede usar la función istream::getline() para extraer caracteres desde un buffer.
Constructores
strstream(); strstream(char*, int sz, int mode);
La primera forma crea un strstream con el buffer del dato miembro strambuf de la clase base strstreambase creado dinámicamente la primera vez que se usa. Las áreas de entrada y salida son la misma.
La segunda forma crea un strstream con un buffer del tamaño especificado. Si el parámetro mode es ios::app o ios::ate, el puntero de entrada/salida se coloca en el carácter nulo que indica el final de la cadena.
Función str
char *str();
Devuelve y bloquea el buffer. El usuario debe liberar el buffer si es dinámico.
Objetos predefinidos
C++ declara y define cuatro objetos predefinidos, uno de la clase istream, y tres más de la clase ostream_withassign estos objetos están disponibles para cualquier programa C++:
- cin: entrada estándar: teclado.
- cout: salida estándar: pantalla.
- cerr: salida sin buffer a pantalla, la salida es inmediata, no es necesario vaciar el buffer.
- clog: igual que cerr, aunque suele redirigirse a un fichero log en disco.
Objeto cout
Se trata de un objeto global definido en "iostream.h".
A lo largo de todo el curso hemos usado el objeto cout sin preocuparnos mucho de lo qué se trataba en realidad, ahora veremos más profundamente este objeto.
El operador <<
Ya conocemos el operador <<, lo hemos usado a menudo para mostrar cadenas de caracteres y variables.
ostream &operator<<(int)
El operador está sobrecargado para todos los tipos estándar: char, char *, void *, int, long, short, bool, double y float.
Además, el operador << devuelve una referencia objeto ostream, de modo que puede asociarse. Estas asociaciones se evalúan de izquierda a derecha, y permiten expresiones como:
cout << "Texto: " << variable << "\n";
C++ reconoce el tipo de la variable y muestra la salida de la forma adecuada, siempre como una cadena de caracteres.
Por ejemplo:
int entero = 10; char caracter = 'c'; char cadena[] = "Hola"; float pi = 3.1416; void *puntero = cadena; cout << "entero=" << entero << endl; cout << "caracter=" << caracter << endl; cout << "cadena=" << cadena << endl; cout << "pi=" << pi << endl; cout << "puntero=" << puntero << endl;
La salida tendrá este aspecto:
entero=10 caracter=c cadena=Hola pi=3.1416 puntero=0x254fdb8
Funciones interesantes de cout
Hay que tener en cuenta que cout es un objeto de la clase "ostream", que a su vez está derivada de la clase "ios", así que heredará todas las funciones y operadores de ambas clases. Se mostrarán todas esas funciones con más detalle en la documentación de las bibliotecas, pero veremos ahora las que se usan más frecuentemente.
Formatear la salida
El formato de las salidas de cout se puede modificar mediante flags. Estos flags pueden leerse o modificarse mediante las funciones flags, setf y unsetf.
Otro medio es usar manipuladores, que son funciones especiales que sirven para cambiar la apariencia de una operación de salida o entrada de un stream. Su efecto sólo es válido para una operación de entrada o salida. Además devuelven una referencia al stream, con lo que pueden ser insertados en una cadena entradas o salidas.
Por el contrario, modificar los flags tiene un efecto permanente, el formato de salida se modifica hasta que se restaure o se modifique el estado del flag.
Funciones manipuladoras con parámetros
Para usar estos manipuladores es necesario incluir el fichero de cabecera iomanip.
Existen seis de estas funciones manipuladoras: setw, setbase, setfill, setprecision, setiosflags y resetiosflags.
Todas trabajan del mismo modo, y afectan sólo a la siguiente entrada o salida.
Manipulador setw
Permite cambiar la anchura en caracteres de la siguiente salida de cout. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { int x = 123, y = 432; cout << "#" << setw(6) << x << "#" << setw(12) << y << "#" << endl; return 0; }
La salida tendrá este aspecto:
# 123# 432#
Manipulador setbase
Permite cambiar la base de numeración que se usará para la salida. Sólo se admiten tres valores: 8, 10 y 16, es decir, octal, decimal y hexadecimal. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { int x = 123; cout << "#" << setbase(8) << x << "#" << setbase(10) << x << "#" << setbase(16) << x << "#" << endl; return 0; }
La salida tendrá este aspecto:
#173#123#7b#
Manipulador setfill
Permite especificar el carácter de relleno cuando la anchura especificada sea mayor de la necesaria para mostrar la salida. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { int x = 123; cout << "#" << setw(8) << setfill('0') << x << "#" << endl; cout << "#" << setw(8) << setfill('%') << x << "#" << endl; return 0; }
La salida tendrá este aspecto:
#00000123# #%%%%%123#
Manipulador setprecision
Permite especificar el número de dígitos significativos que se muestran cuando se imprimen números en punto flotante: float o double. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { float x = 121.0/3; cout << "#" << setprecision(3) << x << "#" << endl; cout << "#" << setprecision(1) << x << "#" << endl; return 0; }
La salida tendrá este aspecto:
#40.3# #4e+01#
Manipuladores setiosflags y resetiosflags
Permiten activar o desactivar, respectivamente, los flags de formato de salida. Existen quince flags de formato a los que se puede acceder mediante un enum definido en la clase ios:
flag | Acción |
---|---|
skipws | ignora espacios en operaciones de lectura |
left | ajusta la salida a la izquierda |
right | ajusta la salida a la derecha |
internal | deja hueco después del signo o el indicador de base |
dec | conversión a decimal |
oct | conversión a octal |
hex | conversión a hexadecimal |
showbase | muestra el indicador de base en la salida |
showpoint | muestra el punto decimal en salidas en punto flotante |
uppercase | muestra las salidas hexadecimales en mayúsculas |
showpos | muestra el signo '+' en enteros positivos |
scientific | muestra los números en punto flotante en notación exponencial |
fixed | usa el punto decimal fijo para números en punto flotante |
unitbuf | vacía todos los buffers después de una inserción |
stdio | vacía los buffers stdout y stderr después de una inserción |
Veamos un ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { float x = 121.0/3; int y = 123; cout << "#" << setiosflags(ios::left) << setw(12) << setprecision(4) << x << "#" << endl; cout << "#" << resetiosflags(ios::left | ios::dec) << setiosflags(ios::hex | ios::showbase | ios::right) << setw(8) << y << "#" << endl; return 0; }
La salida tendrá este aspecto:
#40.33 # # 0x7b#
Manipuladores sin parámetros
Existe otro tipo de manipuladores que no requieren parámetros, y que ofrecen prácticamente la misma funcionalidad que los anteriores. La diferencia es que los cambios son permanentes, es decir, no sólo afectan a la siguiente salida, sino a todas las salidas hasta que se vuelva a modificar el formato afectado.
Manipuladores dec, hex y oct
inline ios& dec(ios& i) inline ios& hex(ios& i) inline ios& oct(ios& i)
Permite cambiar la base de numeración de las salidas de enteros, supongo que resulta evidente, pero de todos modos lo diré.
Función | Acción |
---|---|
dec | Cambia la base de numeración a decimal |
hex | Cambia la base de numeración a hexadecimal |
oct | Cambia la base de numeración a octal |
El cambio persiste hasta un nuevo cambio de base. Ejemplo:
#include <iostream> using namespace std; int main() { int a = 123, c = 432, b = 543; cout << "Decimal: " << dec << a << ", " << b << ", " << c << endl; cout << "Hexadecimal: " << hex << a << ", " << b << ", " << c << endl; cout << "Octal: " << oct << a << ", " << b << ", " << c << endl; return 0; }
La salida tendrá éste aspecto:
Decimal: 123, 543, 432 Hexadecimal: 7b, 21f, 1b0 Octal: 173, 1037, 660
Funciones ws y ends
La función ws sólo es para streams de entrada.
La función ends no tiene sentido en cout, ya que sirve para añadir el carácter nulo de fin de cadena.
Función flush
ostream& flush(ostream& outs);
Vacía el buffer de salida. Puede ser invocada de dos modos:
cout.flush(); cout << flush;
Función endl
ostream& endl(ostream& outs);
Vacía el buffer de salida y además cambia de línea. Puede ser invocada de dos modos:
cout.endl(); cout << 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 la siguiente salida, y también devuelve el valor actual de la anchura.
int x = 23; cout << "#"; cout.width(10); cout << x << "#" << x << "#" << endl;
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 la siguiente salida, y también devuelve el valor actual.
int x = 23; cout << "|"; cout.width(10); cout.fill('%'); cout << x << "|" << x << "|" << endl;
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 la siguiente salida, y también devuelve el valor actual.
float x = 23.45684875; cout << "|"; cout.precision(6); cout << x << "|" << x << "|" << endl;
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 en el parámetro valor y deja sin cambios el resto.
La segunda forma activa los flags que estén activos tanto en valor como en mascara y desactiva los que estén activos en mascara, pero no en valor. Podemos considerar que mascara 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 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 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.
int x = 235; long f; cout << "|"; f = flags(); f &= !(ios::left | ios::right | ios::internal); f |= ios::left; cout.flags(f); cout.width(10); cout << x << "|" << endl;
Función put
Imprime un carácter:
ostream& put(char);
Ejemplo:
char l = 'l'; unsigned char a = 'a'; cout.put('H').put('o').put(l).put(a) << endl;
Función write
Imprime varios caracteres:
ostream& write(char* cad, int n);
Imprime n caracteres desde el principio de la cadena cad. Ejemplo:
char cadena[] = "Cadena de prueba"; cout.write(cadena, 12) << endl;
Función form
Imprime expresiones con formato, es análogo al printf de "stdio":
ostream& form(char* format, ...);
Nota:
Algunos compiladores no disponen de esta función.
Ejemplo:
char l = 'l'; int i = 125; float f = 125.241; char cad[] = "Hola"; cout.form("char: %c, int: %d, float %.2f, char*: %s", l, i, f, cad);
Objeto cin
Se trata de un objeto global definido en "iostream.h".
En ejemplos anteriores ya hemos usado el operador >>.
El operador >>
Ya conocemos el operador >>, lo hemos usado para capturar variables.
istream &operator>>(int&)
Este operador está sobrecargado en cin para los tipos estándar: int&, short&, long&, double&, float&, char& y char*.
Además, el operador << devuelve una referencia objeto ostream, de modo que puede asociarse. Estas asociaciones se evalúan de izquierda a derecha, y permiten expresiones como:
cin >> var1 >> var2; cin >> variable;
Cuando se usa el operador >> para leer cadenas, la lectura se interrumpe al encontrar un carácter '\0', ' ' o '\n'.
Hay que tener cuidado, ya que existe un problema cuando se usa el operador >> para leer cadenas: cin no comprueba el desbordamiento del espacio disponible para el almacenamiento de la cadena, del mismo modo que la función gets tampoco lo hace. De modo que resulta poco seguro usar el operador >> para leer cadenas.
Por ejemplo, declaramos:
char cadena[10]; cin >> cadena;
Si el usuario introduce más de diez caracteres, los caracteres después de décimo se almacenarán en una zona de memoria reservada para otras variables o funciones.
Existe un mecanismo para evitar este problema, consiste en formatear la entrada para limitar el número de caracteres a leer:
char cadena[10]; cin.width(sizeof(cadena)); cin >> cadena;
De este modo, aunque el usuario introduzca una cadena de más de diez caracteres sólo se leerán diez.
Funciones interesantes de cin
Hay que tener en cuenta que cin es un objeto de la clase "istream", que a su vez está derivada de la clase "ios", así que heredará todas las funciones y operadores de ambas clases. Se mostrarán todas esas funciones con más detalle en la documentación de las bibliotecas, pero veremos ahora las que se usan más frecuentemente.
Formatear la entrada
El formato de las entradas de cin, al igual que sucede con cout, se puede modificar mediante flags. Estos flags pueden leerse o modificarse mediante las funciones flags, setf y unsetf.
Otro medio es usar manipuladores, que son funciones especiales que sirven para cambiar la apariencia de una operación de salida o entrada de un stream. Su efecto sólo es válido para una operación de entrada o salida. Además devuelven una referencia al stream, con lo que pueden ser insertados en una cadena entradas o salidas.
Por el contrario, modificar los flags tiene un efecto permanente, el formato de salida se modifica hasta que se restaure o se modifique el estado del flag.
Funciones manipuladoras con parámetros
Para usar estos manipuladores es necesario incluir el fichero de cabecera iomanip.
Existen cuatro de estas funciones manipuladoras aplicables a cin: setw, setbase, setiosflags y resetiosflags.
Todas trabajan del mismo modo, y afectan sólo a la siguiente entrada o salida.
En el caso de cin, no todas las funciones manipuladoras tienen sentido, y algunas trabajan de un modo algo diferentes que con streams de salida.
Manipulador setw
Permite establecer el número de caracteres que se leerán en la siguiente entrada desde cin. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { char cad[10]; cout << "Cadena:" cin >> setw(10) >> cad; cout << cad << endl return 0; }
La salida tendrá este aspecto, por ejemplo:
Cadena: 1234567890123456 123456789
Hay que tener en cuenta que el resto de los caracteres no leídos por sobrepasar los diez caracteres, se quedan en el buffer de entrada de cin, y serán leídos en la siguiente operación de entrada que se haga. Ya veremos algo más abajo cómo evitar eso, cuando veamos la función "ignore".
El manipulador setw no tiene efecto cuando se leen números, por ejemplo:
#include >iostream> #include >iomanip> using namespace std; int main() { int x; cout >> "Entero:" cin >> setw(3) >> x cout >> x >> endl return 0; }
La salida tendrá este aspecto, por ejemplo:
Entero: 1234567 1234567
Manipulador setbase
Permite cambiar la base de numeración que se usará para la entrada de números enteros. Sólo se admiten tres valores: 8, 10 y 16, es decir, octal, decimal y hexadecimal. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { int x; cout << "Entero: "; cin >> setbase(16) >> x; cout << "Decimal: " << x << endl; return 0; }
La salida tendrá este aspecto:
Entero: fed4 Decimal: 65236
Manipuladores setiosflags y resetiosflags
Permiten activar o desactivar, respectivamente, los flags de formato de entrada. Existen quince flags de formato a los que se puede acceder mediante un enum definido en la clase ios:
flag | Acción |
---|---|
skipws | ignora espacios en operaciones de lectura |
left | ajusta la salida a la izquierda |
right | ajusta la salida a la derecha |
internal | deja hueco después del signo o el indicador de base |
dec | conversión a decimal |
oct | conversión a octal |
hex | conversión a hexadecimal |
showbase | muestra el indicador de base en la salida |
showpoint | muestra el punto decimal en salidas en punto flotante |
uppercase | muestra las salidas hexadecimales en mayúsculas |
showpos | muestra el signo '+' en enteros positivos |
scientific | muestra los números en punto flotante en notación exponencial |
fixed | usa el punto decimal fijo para números en punto flotante |
unitbuf | vacía todos los buffers después de una inserción |
stdio | vacía los buffers stdout y stderr después de una inserción |
De los flags de formato listados, sólo tienen sentido en cin los siguientes: skipws, dec, oct y hex.
Veamos un ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { char cad[10]; cout << "Cadena: "; cin >> setiosflags(ios::skipws) >> cad; cout << "Cadena: " << cad << endl; return 0; }
La salida tendrá este aspecto:
Cadena: prueba Cadena: prueba
Manipuladores sin parámetros
Existen otro tipo de manipuladores que no requieren parámetros, y que ofrecen prácticamente la misma funcionalidad que los anteriores. La diferencia es que los cambios son permanentes, es decir, no sólo afectan a la siguiente entrada, sino a todas las entradas hasta que se vuelva a modificar el formato afectado.
Manipuladores dec, hex y oct
inline ios& dec(ios& i) inline ios& hex(ios& i) inline ios& oct(ios& i)
Permite cambiar la base de numeración de las entradas de enteros:
Función | Acción |
---|---|
dec | Cambia la base de numeración a decimal |
hex | Cambia la base de numeración a hexadecimal |
oct | Cambia la base de numeración a octal |
El cambio persiste hasta un nuevo cambio de base. Ejemplo:
#include <iostream> using namespace std; int main() { int x, y, z; cout << "Entero decimal (x y z): "; cin >> dec >> x >> y >> z; cout << "Enteros: " << x << ", " << y << ", " << z << endl; cout << "Entero octal (x y z): "; cin >> oct >> x >> y >> z; cout << "Enteros: " << x << ", " << y << ", " << z << endl; cout << "Entero hexadecimal (x y z): "; cin >> hex >> x >> y >> z; cout << "Enteros: " << x << ", " << y << ", " << z << endl; return 0; }
La salida tendrá éste aspecto:
Entero decimal (x y z): 10 45 25 Enteros: 10, 45, 25 Entero octal (x y z): 74 12 35 Enteros: 60, 10, 29 Entero hexadecimal (x y z): de f5 ff Enteros: 222, 245, 255
Función ws
extern istream& ws(istream& ins);
Ignora los espacios iniciales en una entrada de cadena. Ejemplo:
#include <iostream> using namespace std; int main() { char cad[10]; cout << "Cadena: "; cin >> ws >> cad; cout << "Cadena: " << cad << endl; return 0; }
La salida tendrá éste aspecto:
Cadena: hola Cadena: hola
Función width()
Cambia la anchura en caracteres de la siguiente entrada de stream:
int width(); int width(int);
La primera forma devuelve el valor de la anchura actual, la segunda permite cambiar la anchura para la siguiente entrada, y también devuelve el valor actual de la anchura. Esta función no tiene efecto con variables que no sean de tipo cadena.
char cadena[10]; cin.width(sizeof(cadena)); cin >> cadena;
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; cin.setf(ios::oct, ios::dec | ios::oct | ios::hex); cin >> x;
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; cin.unsetf(ios::dec | ios::oct | ios::hex); cin.setf(ios::hex); cin >> x;
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.
int x; long f; f = flags(); f &= !(ios::hex | ios::oct | ios::dec); f |= ios::dec; cin.flags(f); cin >> x;
Función get
La función get() tiene tres formatos:
int get(); istream& get(char& c); istream& get(char* ptr, int len, char delim = '\n');
Sin parámetros, lee un carácter, y lo devuelve como valor de retorno:
Nota:
Esta forma de la función get() se considera obsoleta.
Con un parámetro, lee un carácter:
En este formato, la función puede asociarse, ya que el valor de retorno es una referencia a un stream. Por ejemplo:
char a, b, c; cin.get(a).get(b).get(c);
Con tres parámetros: lee una cadena de caracteres:
En este formato la función get lee caracteres hasta un máximo de 'len' caracteres o hasta que se encuentre el carácter delimitador.
char cadena[20]; cin.get(cadena, 20, '#');
Función getline
Funciona exactamente igual que la versión con tres parámetros de la función get(), salvo que el carácter delimitador también se lee, en la función get() no.
istream& getline(char* ptr, int len, char delim = '\n');
Función read
Lee n caracteres desde el cin y los almacena a partir de la dirección ptr.
istream& read(char* ptr, int n);
Función ignore
Ignora los caracteres que aún están pendientes de ser leídos:
istream& ignore(int n=1, int delim = EOF);
Esta función es útil para eliminar los caracteres sobrantes después de hacer una lectura con el operador >>, get o getline; cuando leemos con una achura determinada y no nos interesa el resto de los caracteres introducidos. Por ejemplo:
#include <iostream> #include <iomanip> using namespace std; int main() { char cad[10]; int i; cout << "Cadena: "; cin >> setw(10) >> cad; cout << "Entero: "; cin.ignore(100, '\n') >> i; cout << "Cadena: " << cad << endl; cout << "Entero: " << i << endl; cin.get(); return 0; }
La salida podría tener este aspecto:
Cadena: cadenademasiadolarga Entero: 123 Cadena: cadenadem Entero: 123
Función peek
Esta función obtiene el siguiente carácter del buffer de entrada, pero no lo retira, lo deja donde está.
int peek();
Función putback
Coloca un carácter en el buffer de entrada:
istream& putback(char);
Función scan
Lee variables con formato, es análogo al scanf de "stdio":
istream& scan(char* format, ...);
Nota:
Algunos compiladores no disponen de esta función.
Ejemplo:
char l; int i; float f; char cad[15]; cin.scan("%c%d%f%s", &l, &i, &f, cad);