Formato de salida con la instrucción cout Por Fabian Gentile Un medio de formatear la salida 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. Para usar estos manipuladores es necesario incluir el fichero de cabecera iomanip (iomanip.h). M anipuladores con parámetros: Existen seis de estas funciones manipuladoras con parametros: setw, setbase, setfill, setprecision, setiosflags y resetiosflags. M anipulador setw : Permite cambiar la anchura en caracteres de la siguiente salida de cout. Por ejemplo: #include <iostream.h> #include <iomanip.h> void main() { int x = 123, y = 432; cout << "#" << setw(6) << x << "#" << setw(12) << y << "#" << endl; } La salida tendrá este aspecto: # 123# 432# M anipulador 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.h> #include <iomanip.h> void main() { int x = 123; cout << "#" << setbase(8) << x << "#" << setbase(10) << x << "#" << setbase(16) << x << "#" << endl; } La salida tendrá este aspecto: #173#123#7b# M anipulador 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.h> #include <iomanip.h> void main() { int x = 123; cout << "#" << setw(8) << setfill('0') << x << "#" << endl; cout << "#" << setw(8) << setfill('%') << x << "#" << endl; } La salida tendrá este aspecto: #00000123# #%%%%%123# M anipulador setp recision : 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.h> #include <iomanip.h> void main() { float x = 121.0/3; cout << "#" << setprecision(3) << x << "#" << endl; cout << "#" << setprecision(1) << x << "#" << endl; } La salida tendrá este aspecto: #40.333# #40.3# Manipulador es setiosflags y r esetiosflags: 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.h> #include <iomanip.h> void 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; } La salida tendrá este aspecto: #40.3333 # # 0x7b# Manipuladores sin par ámetr os: 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. Manipulador es dec, hex y oct 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.h> void 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; } La salida tendrá éste aspecto: Decimal: 123, 543, 432 Hexadecimal: 7b, 21f, 1b0 Octal: 173, 1037, 660 Entrada de datos por teclado utilizando cin y s us pos ibles errores por Fabián Gentile Un programa correctamente escrito no solo lee la entrada de datos sino que la valida. Si el mismo espera un valor numérico y el usuario ingresa otro carácter, el programa que utiliza la instrucción cin generará un error y entrara en un ciclo sin fin. Para que esto no ocurra hay que trabajar utilizando la validación de la instrucción cin Ejemplo n°1 Este programa genera un error y no finaliza debido a que si se ingresa un caracter en vez de un valor numérico entra en un ciclo sin fin e imprime basura. // Ejemplo n°1 // Este programa no funciona correctamente #include <iostream.h> #include <conio.h> void main(){ int x = 0; clrscr(); do { cout << "Ingrese un numero (­1 para salir): "; cin >> x; if(x != ­1) { cout << "Usted ingreso " << x << endl; } } while(x != ­1); cout << "Fin del programa" << endl; getch() ; } presione Ctrl+C. para abortar el programa Reparando el Stream (ingreso) cuando ocurre un error de ingreso el stream se rompe y devuelve el valor falso (0) Para repararlo hay que hacer dos cosas 1­Limpiar el error con la instrucción: cin.clear(); que prepara el stream para su uso normal de nuevo. Pero realizar esto solo no es suficiente. 2­ Hay que sacar los caracteres del stream que el usuario ingreso por error Ejemplo n°2 Este ejemplo ingresa y valida el error correctamente enviándolo por pantalla. Para eso se declara una cadena de caracteres para guardar el error. // Ejemplo n°2 // este programa funciona correctamente #include <iostream.h> #include <conio.h> void main(){ int x = 0; char malChars[200]; // para guardar el ingreso erróneo clrscr(); do { cout << "Ingrese un numero (­1 para salir): "; if(!(cin >> x)) { // valida el error en cin cin.clear(); // arregla el stream cin >> malChars; // limpia el stream cout<<"usted ingreso "<< malChars<<" en lugar de un numérico."<<endl; } }while(x != ­1); cout << "Fin del programa" << endl; getch(); } Si no desea usar los caracteres ingresados por error se usa la instrucción cin.ignore(200,'\n'); que significa ignore 200 caracteres(el valor 200 puede ser mayor o menor) o hasta que se ingrese enter. Ejemplo n°3 Este ejemplo ingresa y valida el error correctamente sin mostrar por pantalla el ingreso erróneo //Ejemplo n°3 //este programa funciona correctamente #include <iostream.h> #include <conio.h> void main(){ int x = 0; clrscr(); do { cout << "Ingrese un numero (­1 para salir): "; if(!(cin >> x)) { // valida el error en cin cin.clear(); // arregla el stream cin.ignore(200,'\n');// ignora el ingreso de hasta 200 caracteres } }while(x != ­1); cout << "Fin del programa" << endl; getch(); }