deas 2015

Hasta ahora los programas creados nos han expresado poca interacción con el usuario no es verdad?. Simplemente nos muestran valores simples en pantalla y nosotros queremos hacer muchas otras cosas con C++.
Pues bien, para dejar de ser aburrido, C++ nos da a conocer que su biblioteca estándar std ofrece muchas otras maneras de interactuar con el usuario a través de sus características de Entrada y Salida "Input y Output". En esta parte del tutorial mostraré una breve introducción a algunas de esas interezantes características y para eso dejaré muchos ejemplos fáciles y otros más complejos para que haya práctica y se aprenda más rápido.
C++ utiliza una abstracción apropiada llamada stream la cual realiza las operaciones de entrada y salida en medios secuenciales como la pantalla, el teclado o un archivo. Un stream es una entidad en la que un programa puede insertar o extraer caracteres para/hacia "to/from"algun lugar. No es necesario conocer detalles o especificaciones internas sobre los medios asociados al stream; lo que si es importante conocer es que los stream son una fuente/destino source/destination de caracteres y que estos caracteres son proporcionados y aceptados secuencialmente(es decir, uno tras otro).
La biblioteca estándar std define un manojo de objetos stream que se pueden utilizar para acceder a lo que se consideran fuentes y destinos standard de los caracteres por el entorno donde se ejecuta el programa:
flujodescripción
cin flujo stream de entrada standard
cout flujo stream de salida standard
cerr flujo stream de error padrón standard (salida)
clog flujo stream de registro estándar (salida)
Vamos a enfocarnos con más detalle sólo en cout y cin (la entrada y salida standard de stream); cerr y clog son también streams de salida (outputs), pero básicamente funcionan como cout, con la única diferencia de que estos identifican streams de propósitos específicos: mensajes de error y registros; que en muchos casos mayormente en configuraciones de ambientes, hacen exactamente lo mismo: imprimen en pantalla.

Salida Standard (cout)

La mayoría de los entornos de programas tienen como salida standard la pantalla y el objeto stream C++ definido para acceder a ella es cout. Para las operaciones de salida formateadas, cout se utiliza junto con el operador de inserción, que se escribe como << (es decir dos signos menor que).
cout << "frase de salida"; // Imprime frase de salida en pantalla
cout << 120;  // imprime el numero 120 en pantalla
cout << x;  // imprime el valor de x en pantalla
El operador << inserta los datos que le siguen en la secuencia que lo precede. En los ejemplos anteriores por ejemplo, se insertó la cadena literal "frase de salida"; el número 120 y el valor de la variable x en el flujo de salida output standard. Observe que la oración de la primera instrucción está entre comillas dobles (") porque es una cadena literal, mientras que en la ultima, x no lo es. La doble comilla es lo que hace la diferencia, cuando el texto está entre ellas, este se imprime literalmente; cuando no lo está; este texto se interpreta como si estuviera identificando a una variable y su valor se imprime en su lugar. Por ejemplo estas dos frases tienen resultados muy diferentes:
cout << "Hello"; //Imprime en Pantalla la palabra: "Hello"
cout << Hello; //Imprime en pantalla el contenido de la variable Hello
Múltiples operaciones de inserción (<<) pueden estar concatenados en una única declaración también. Vean:
cout << "Esta " << "es una " << "única declaración C++";
Esta última declaración imprimirá en pantalla el texto: "Esta es una única declaración C++". Las inserciones de encadenamiento son especialmente útiles para mezclar literales y variables en una única declaración. Como pueden ver lo que no hace cout automaticamente es agregar saltos de línea al final, a menos que se lo indiquen manualmente. Por ejemplo, tome las siguientes dos instrucciones insertándolas con cout:
cout << "Esta es una sentencia";
cout << "Esta es otra sentencia";
La salida sería en una sola línea, sin ningún salto de línea al final de cada sentencia; algo como: Esta es una sentencia. Esta es otra sentencia. Para insertar un salto de línea, se insertará un carácter de nueva línea en la posición exacta en que se desea romper la línea. En C++, un caracter de nueva línea se puede especificar con \n (es decir un carácter de barra diagonal inversa seguida de una n minúscula). Por ejemplo:
cout << "Primera sentencia. \n";
cout << "Segunda sentencia.\nTercera Sentencia.";
Esto produce la siguiente salida:
Primera sentencia.
Segunda sentencia.
Tercera Sentencia.
Alternativamente el manipulador endl también puede usarse para romper líneas. Por ejemplo:
cout << "Primera Sentencia." << endl;
cout << "Segunda Sentencia."<< endl;
Esto imprimirá:
Primera Sentencia.
Segunda Sentencia.
El manipulador endl produce un caracter de nueva línea, exactamente como lo hace la inserción de \n; pero también tiene un comportamiento adicional: el búfer de stream o bufer de flujo (si es que hay alguno) es vaciado, lo que significa que se pide que la salida se escriba físicamente en el dispositivo; si es que aún no lo estaba. Esto afecta principalmente a los streams de almacenamiento en bufer y cout (en general) no es un stream completamente almacenado en búfer. Sin embargo, se deberia usar endl siempre y cuando la limpieza del stream sea una característica y \n cuando no lo sea. Tenga en mente que una operación de limpieza incurre en una cierta sobrecarga y en algunos dispositivos puede producir un retraso. [tab] [content title="Primer Ejemplo"]
//Inputs e Outputs básicos
#include <iostream>
using namespace std;

int main()
{
    cout << "Frase de salida.\n";
    cout << 120 << "\n";
    int x = 3;
    cout << x << "\n";
    return 0;
}
[/content] [content title="Segundo Ejemplo"]
#include <iostream>
using namespace std;

int main()
{
    string hello = "Soy la traducción de hola al inglés";
    cout << "hello" << ".\n";
    cout << hello << ".\n";
    return 0;
}
[/content] [content title="Tercer Ejemplo"]
//Inputs e Outputs básicos
#include <iostream>
using namespace std;

int main()
{
    cout << "Esta es una sentencia.";
    cout << "Esta es otra sentencia.";
    return 0;
}
[/content] [/tab]

Entrada estándar (cin)

En la mayoría de los entornos de programa, la entrada estándar de forma predeterminada es el teclado, y el objeto de flujo stream de C ++ definido para acceder es cinPara operaciones de entrada formateadas, cinse utiliza junto con el operador de extracción, que se escribe como >>(es decir, dos signos "mayores que"). Este operador es seguido por la variable donde se almacenan los datos extraídos. Por ejemplo:
int age;
cin << age;
La primera declaración declara una variable de tipo int llamada edad, y la segunda extrae de cin un valor para ser almacenado en ella. Esta operación hace que el programa espere la entrada de cingeneralmente, esto significa que el programa esperará a que el usuario introduzca alguna secuencia con el teclado. En este caso, tenga en cuenta que los caracteres introducidos mediante el teclado sólo se transmiten al programa cuando se pulsa la tecla ENTER(o RETURN). Una vez que cin haya alcanzado la instrucción con la operación de extracción , el programa esperará el tiempo que sea necesario hasta que se introduzca alguna entrada. La operación de extracción cin utiliza el tipo de variable después del >> operador para determinar cómo interpreta los caracteres leídos de la entrada; si es un entero, el formato esperado es una serie de dígitos, si es una cadena una secuencia de caracteres, etc.
//Inputs e Outputs básicos
#include <iostream>
using namespace std;

int main()
{
    int i;
    cout << "Por favor ingrese un valor entero: ";
    cin >> i;
    cout << "El valor que usted ingresó es: " << i;
    cout << " y el doble es: " << i * 2 << "\n";
    return 0;
}
Como puede ver, extraer de cinparece hacer que la tarea de obtener información de entrada estándar sea bastante simple y directa. Pero este método también tiene un gran inconveniente. ¿Qué sucede en el ejemplo anterior si el usuario introduce algo que no puede ser interpretado como un entero? Bueno, en este caso, la operación de extracción falla. Y esto, de forma predeterminada, permite que el programa continúe sin establecer un valor para la variable i, produciendo resultados indeterminados si el valor de i se utiliza posteriormente. Esto es un comportamiento muy pobre del programa. Se espera que la mayoría de los programas se comporten de una manera esperada sin importar lo que diga el usuario, manejando valores no válidos apropiadamente. Solamente los programas muy simples deben confiar en los valores extraídos directamente de cinsin la comprobación adicional. Un poco más adelante veremos cómostringstreams se puede utilizar para tener un mejor control sobre la entrada del usuario. Las extracciones en cintambién se pueden encadenar para solicitar más de un dato en una única sentencia:
cin >> a >> b;
Esto es equivalente a:
cin >> a;
cin >> b;
En ambos casos, se espera que el usuario introduzca dos valores, uno para variable ay otro para variable bCualquier espacio se utiliza para separar dos operaciones de entrada consecutivas; esto puede ser un espacio, una pestaña o un carácter de nueva línea.

cin y strings

El operador de extracción se puede utilizar cin para obtener cadenas strings de caracteres de la misma manera que con los tipos de datos fundamentales:
string mystring;
cin >> mystring;
Sin embargo, cin de extracción siempre considera espacios (espacios en blanco, pestañas, nueva línea ...) como terminando el valor que se está extrayendo, y extraer una cadena significa extraer siempre una sola palabra, no una frase o una oración entera. Para obtener una línea completa de cin, existe una función, llamada getline, que toma el stream ( cin) como primer argumento, y la variable de cadena como segundo. Por ejemplo:
#include<iostream>
#include<string>
using namespace std;

int main()
{
  string mistring;
  cout << "Cuál es su nombre? ";
  getline(cin,mistring);
  cout << "Hola " << mistring << ".\n";
  cout << "Cuál es su equipo favorito? ";
  getline(cin,mistring);
  cout << "Yo soy del "<< mistring << " yo tambien!\n";
  return 0;
}
Observe cómo en ambas llamadas a getline, usamos el mismo identificador de cadena ( mystr). Lo que hace el programa en la segunda llamada es simplemente reemplazar el contenido anterior con el nuevo que se introduce. El comportamiento estándar que la mayoría de los usuarios esperan de un programa de consola es que cada vez que el programa consulta al usuario para que ingrese, el usuario introduce el campo y luego presiona ENTER(o RETURN). Es decir, generalmente se espera que la entrada ocurra en términos de líneas en los programas de la consola, y esto se puede lograr usando getlinepara obtener la entrada del usuario. Por lo tanto, a menos que tenga una buena razón para no hacerlo, siempre debe utilizar getlinepara obtener entrada en sus programas de consola en lugar de extraer de cin.

stringstream

El encabezado estándar <sstream>define un tipo llamado stringstreamque permite que una cadena sea tratada como un flujo y, por lo tanto, permite extraer o insertar operaciones de / a cadenas de la misma manera en que se realizan en cincoutEsta característica es más útil para convertir cadenas a valores numéricos y viceversa. Por ejemplo, para extraer un entero de una cadena podemos escribir:
string mystr ("1204");
int myint;
stringstream(mystr) >> myint;
Esto declara a stringcon inicializado a un valor de "1204", y una variable de tipo intA continuación, la tercera línea utiliza esta variable para extraer de un stringstreamconstruido a partir de la cadena. Esta pieza de código almacena el valor numérico 1204en la variable llamada myint.
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main ()
{
  string mystr;
  float precio=0;
  int cantidad=0;

  cout << "Entre su precio: ";
  getline (cin,mystr);
  stringstream(mystr) >> precio;
  cout << "Entrar cantidad: ";
  getline (cin,mystr);
  stringstream(mystr) >> cantidad;
  cout << "Precio Total: " << precio * cantidad << endl;
  return 0;
}
En este ejemplo, adquirimos valores numéricos de la entrada estándar de forma indirecta: en lugar de extraer valores numéricos directamente de cin, obtenemos líneas de ella en un objeto de cadena ( mystr), y luego extraemos los valores de esta cadena en las variables pricequantityUna vez que se trata de valores numéricos, se pueden realizar operaciones aritméticas sobre ellos, como multiplicarlos para obtener un precio total. Con este enfoque de obtener líneas enteras y extraer sus contenidos, separamos el proceso de obtener información del usuario de su interpretación como datos, permitiendo que el proceso de entrada sea lo que el usuario espera y, al mismo tiempo, ganando más control sobre la transformación de su contenido en datos útiles por el programa.

Habiendo entendido correctamente este capítulo, estaremos habilitados para praticar los ejemplos con diferentes valores. Esto hará más prolijo su camino hacia el entendimiento del lenguaje. Ya más adelante comenzaremos a crear mucho código interesante!. Repito!, no deje de practicar, eso es vital!

Publicar un comentario

Con la tecnología de Blogger.