Curso de C++ v2.0
Consultas, lista de correo 'C++ Con Clase' 'C++ Con Clase' página de entrada Librerías estándar C Tabla de contenido Contactar con Webmaster
*Introducción
*1 Toma de contacto
*2 Variables I
*3 Funciones I: Declaración y definición
*4 Operadores I
*5 Sentencias
*6 Declaración de variables
*7 Normas para la notación
*8 Cadenas de caracteres
*9 Conversión de tipos
*10 Variables II: Arrays
*11 Variables III: Estructuras
*12 Variables IV: Punteros 1
*13 Operadores II: Más operadores
*14 Operadores III: Precedencia
*15 Funciones II: Parámetros por valor y referencia
*16 Variables V: Uniones
*17 Variables VI: Punteros 2
*18 Operadores IV: De bits y condicional
*19 Definición de tipos
*20 Funciones III
*21 Funciones IV: Sobrecarga
*22 Operadores V: Sobrecarga
*23 El preprocesador
*24 Funciones V: Recursividad
*25 Variables VII: Modificadores
*26 Espacios con nombre
*27 Clases I: Definiciones
*28 Declaración de clases
*29 Constructores
*30 Destructores
*31 El puntero this
*32 Sistema de protección
*33 Modificadores para miembros
*34 Más sobre funciones
*35 Operadores sobrecargados
*36 Herencia
*37 Funciones virtuales
*38 Derivación múltiple
*39 Trabajar con ficheros
*40 Plantillas
*41 Punteros a miembros
*42 Castings
*43 Excepciones
*Ejemplos capítulos 1 a 6
*Ejemplos capítulos 8 y 9
*A Palabras reservadas C/C++
*B Trigrafos y símbolos alternativos
*C Librerías estándar
*D Streams
 . Clases predefinidas
 . streambuf
 . ios
 . filebuf
 . istream
 . ostream
 . iostream
 . fstreambase
 . ifstream
 . ofstream
 . fstream
 . strstreambuf
 . strstreambase
 . istrstream
 . ostrfstream
 . strstream
 . Objetos predefinidos
 . Objeto cout
 . Objeto cin
<< < >

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";
cout << variable;

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 librerías, 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;
   
   ucin.get();
   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);
<< < >