La salida estándar std::cout

Concepto de flujo (stream)

Un flujo (stream) es un canal a través del cual fluyen en serie bytes desde un origen a un destino. Un flujo se implementa internamente con el concurso de un búfer (buffer), una zona de memoria donde se almacenan temporalmente los datos siguiendo una estructura tipo cola (queue), es decir, primero en llegar, primero en salir.

La biblioteca iostream tiene una variable predefinida para un flujo de caracteres (bytes) de salida llamada cout (character output), lo que permite enviar datos a la consola para ser imprimidos como texto.

#include <iostream>

int main()
{
   std::cout << "Hola mundo.";
}

Edita, compila y ejecuta el código

Analicemos este programa:

  1. #include <iostream>

    informamos al compilador nuestro deseo de utilizar funciones de E/S.

  2. std::cout

    la variable cout pertenece al espacio de nombres std.

  3. <<

    operador de inserción, que permite insertar caracteres al flujo de salida cout.

  4. "Hola mundo."

    es una constante literal cadena de caracteres.

El efecto del operador de inserción pude verse en el siguiente ejemplo, cuya salida es idéntica a la del programa anterior. Así, el operador << concatena de izquierda a derecha al flujo de salida cout la cadena "Hola " y luego la cadena "mundo.".

#include <iostream>

int main()
{
   std::cout << "Hola " << "mundo.";
}

Edita, compila y ejecuta el código

¿Qué ocurre si suprimimos la línea #include <iostream>?

//#include <iostream>

int main()
{
   std::cout << "Hola " << "mundo.";
}

Edita, compila y ejecuta el código

Al compilar tendremos un error similar a error: 'cout' is not a member of 'std' o error: use of undeclared identifier 'std'.

El error se debe a que el compilador no encuentra la declaración de cout al no haber incluido la cabecera de la biblioteca iostream o no encuentra ni siquiera el espacio de nombres std.

Nota

Los mensajes de error y la información asociada varían dependiendo del compilador que utilicemos.

¿Qué ocurre si no usamos la resolución de ámbito std::?

#include <iostream>

int main()
{
   cout << "Hola " << "mundo.";
}

Edita, compila y ejecuta el código

Al compilar tendremos un error similar a error: 'cout' was not declared in this scope.

En este caso, el compilador no sabe a qué nos referimos con el identificador cout, es incapaz de relacionarlo con el identificador std::cout que sí está presente en iostream.

Alternativas al uso de la resolución de ámbito ::

Usar la resolución de ámbito con el operador :: es la fórmula recomendada y profesional. Es cierto que este operador recarga el código, haciéndolo prolijo visualmente y tedioso al escribirlo.

Como alternativa y, en particular, para un curso introductorio, puede optarse por utilizar la directiva using de la siguiente forma:

#include <iostream>

using namespace std;

int main()
{
   cout << "Hola " << "mundo.";
}

En el ejemplo, la línea using namespace std; informa al compilador de que, si algún identificador no está declarado, entonces debe buscarlo en el espacio de nombres std.

Transformando representaciones numéricas a cadenas de caracteres

Una de las funcionalidades de la biblioteca iostream es que permite insertar en el flujo de caracteres de salida cout datos numéricos y transformarlos, de forma transparente al usuario, a una representación como cadena de caracteres.

#include <iostream>

int main()
{
   int x = 3;
   double y = 8.13;
   std::cout << "x=" << x << ", y=" << y;
}

Edita, compila y ejecuta el código

Nótese que el efecto final ha sido crear el flujo de caracteres de salida x=3, y=8.13.

Salida en múltiples líneas

En ocasiones se desea imprimir por la consola datos en diferentes líneas. Veamos qué ocurre en el siguiente ejemplo.

#include <iostream>

int main()
{
   int x = 3;
   double y = 8.13;
   std::cout << "x=" << x;
   std::cout << "y=" << y;
}

Edita, compila y ejecuta el código

La salida mostrada es x=3y=8.13. Es algo normal, pues en ningún caso hemos introducido en el flujo de salida el carácter nueva línea, '\n'.

Dependiendo del entorno de ejecución del programa, también se observará que el prompt de la consola (símbolo $ o similar) aparece a continuación de la salida del programa.

Una forma de forzar una nueva línea es mediante std::endl cuyo objetivo es:

  • insertar en el flujo de salida ese carácter

  • vaciar (flush) el flujo de caracteres, forzándolo a ser mostrado en la consola

#include <iostream>

int main()
{
   int x = 3;
   double y = 8.13;
   std::cout << "x=" << x << std::endl;
   std::cout << "y=" << y << std::endl;
}

Edita, compila y ejecuta el código

Una alternativa habitual al uso de std::endl es utilizar directamente el carácter nueva línea '\n'.

#include <iostream>

int main()
{
   int x = 3;
   double y = 8.13;
   std::cout << "x=" << x << "\ny=" << y << '\n';
}

Edita, compila y ejecuta el código