Está en la página 1de 12

Gua#1

UESFIAEIEPEL115

1/12

Universidad de El Salvador Facultad de Ingeniera y Arquitectura Escuela de Ingeniera Elctrica

PROGRAMACIN I
Gua de Laboratorio #1 Tema: E/S en C++

Profesor:

Ing. Walter Zelaya

wzelaya@ing.ues.edu.sv ingwzelaya-pel115@yahoo.com cpocasangre@ing.ues.edu.sv copocasangre@gmail.com

Instructor:

Ing. Carlos Osmn Pocasangre

CICLOII2012

Gua#1

UESFIAEIEPEL115

2/12

INTRODUCCIN:
La presente gua incluye los temas entrada / salida con formato y archivos secuenciales en C++. Se presentan las clases, funciones miembros, indicadores y manipuladores usados para generar reportes en el monitor o en algn archivo, todo esto se encuentra en un pequeo marco terico. Adems se hace uso de cuatro ejemplo que sealan la ruta hacia el dominio de la entrada y salida en C++.

OBJETIVOS:
Al finalizar esta practica de laboratorio el estudiante debe ser capaz de: Utilizar las clases de entrada y salida con formato junto con todos las ordenes de formato, indicadores, manipuladores. Abrir, escribir, leer, cerrar archivos secuenciales de texto o binarios.

ENTRADA / SALIDA EN C++


C++ dispone de unas herramientas propias de entrada y salida de datos basadas en clases y en la herencia que son fciles de extender y modificar. Es necesario recordar aqu el concepto de stream o flujo, que se puede definir como dispositivo que produce o consume informacin. Un flujo est siempre ligado a un dispositivo fsico. Todos los flujos, independientemente del dispositivo fsico al que se dirijan (disco, monitor, etc.) se comportan de forma anloga. C++ dispone de dos jerarquas de clases para las operaciones de entrada / salida: una de bajo nivel, streambuf, que no se va a explicar porque slo es utilizada por programadores expertos, y otra de alto nivel, con las clases: istream -> Gestiona las corrientes de entrada. ostream -> Gestiona las corrientes de salida. iostream -> Gestiona las corrientes de I/O. Que derivan de la clase ios. Estas clases disponen de variables y mtodos para controlar los flujos de entrada salida. Al ejecutarse un programa en C++ se abren automticamente los flujos siguientes: cin: entrada estndar (teclado) (objeto istream) cout: salida estndar (pantalla de monitor) (objeto ostream) cerr: salida de mensajes de error (pantalla) (objeto ostream) Los operadores de desplazamiento a nivel de bits (<< y >>) estn sobrecargados para el manejo de flujos as: << >> Ejemplo: cout<<"hola mundo"; hace que se escriba en pantalla : hola mundo Operador de insercin, est sobrecargado, controla la salida de informacin en general. Operador de extraccin. Entrada de informacin en general, tambin est sobrecargado.

CICLOII2012

Gua#1

UESFIAEIEPEL115

3/12

y: cin>>x; espera a que el usuario introduzca la variable x por teclado.

Indicadores de entrada/salida
Cada flujo de C++ tiene asociados unos indicadores, que son unas variables miembro enum de tipo long que controlan el formato al activarse o desactivarse alguno de sus bits. Dichos bits y su significado son los siguientes: skipws: left: right: internal: dec: oct: hex: showbase: showpoint: uppercase : showpos: scientific: fixed: unitbuf: stdio se descartan los blancos iniciales a la entrada la salida se alinea a la izquierda la salida se alinea a la derecha se alinea el signo y los caracteres indicativos de la base por la izquierda y las cifras por la derecha salida decimal para enteros (defecto) salida octal para enteros salida hexadecimal para enteros se muestra la base de los valores numricos se muestra el punto decimal los caracteres de formato aparecen en maysculas se muestra el signo (+) en los valores positivos notacin cientfica para coma flotante notacin normal para coma flotante. salida sin buffer (se vuelca cada operacin) permite compatibilizar entrada / salida al modo de C con <stdio.h> y al modo de C++ con <iostream.h>.

La forma de definir las constantes anteriores permite componerlas fcilmente, guardando toda la informacin sobre ellas en una nica variable long. Existen unos indicadores adicionales (adjustfield, basefield y floatfield) que actan como combinaciones de los anteriores (mscaras): adjustfield es una combinacin excluyente (slo una en on) de left, rigth e internal basefield es una combinacin excluyente (slo una en on) de dec, oct e hex floatfield es una combinacin excluyente (slo una en on) de scientific y fixed Por defecto todos los indicadores anteriores estn desactivados, excepto skipws y dec.

Activar y desactivar indicadores


Para la activacin de indicadores se pueden utilizar los mtodos setf() y flags() de la clase ios. Se comenzar viendo la primera de ellas. Los dos prototipos del mtodo setf() son: long setf(long indicador); long setf(long indicador, long mask); El valor de retorno de esta funcin, es la configuracin anterior (interesa disponer de ella al hacer algn cambio para poder volver a dicha configuracin si se desea), e indicador es el long que contiene los indicadores. En el segundo prototipo mask es uno de los tres indicadores combinacin de otros (adjustfield, basefield y floatfield).
CICLOII2012

Gua#1

UESFIAEIEPEL115

4/12

Se permite activar varios indicadores a la vez con el operador lgico OR binario. Ejemplo: cout.setf(ios::showpoint | ios::fixed);

Es necesario determinar el flujo afectado (cout) y la clase en la que estn definidos los indicadores (ios). Para desactivar los indicadores se utiliza la funcin unsetf() de modo similar a setf(). El segundo prototipo se debe utilizar para cambiar los indicadores que son exclusivos, como por ejemplo: cout.setf(ios::left, ios::adjustfield); que lo que hace es desactivar los tres bits que tienen que ver con la alineacin y despus activar el bit de alineacin por la izquierda. En la forma, cout.setf(0, ios::adjustfield); pone los tres bits de alineacin a cero.

La funcin flags() sin argumentos devuelve un long con la configuracin de todos los indicadores. Su prototipo es: long flags(); Existe otra definicin de la funcin flags() cuyo valor de retorno es un long con la configuracin anterior, que permite cambiar todos los indicadores a la vez, pasando un long con la nueva configuracin como argumento: long flags(long indic); donde indic contiene una descripcin completa de la nueva configuracin. El inconveniente de la funcin flags() es que establece una nueva configuracin partiendo de cero, mientras que setf() simplemente modifica la configuracin anterior manteniendo todo lo que no se ha cambiado explcitamente, por lo que debe ser considerada como una opcin ms segura. Se presenta a continuacin un ejemplo con todo lo citado hasta ahora: // se mostrar el signo + para nmeros positivos cout.setf(ios::showpos); // se mostrar el punto y no se utilizar notacin cientfica cout.setf(ios::showpoint | ios::fixed); cout << 100.0; que hace que se escriba por pantalla: +100.000000

CICLOII2012

Gua#1

UESFIAEIEPEL115

5/12

Funciones miembro width(), precision() y fill()


Estas funciones estn declaradas en ios y definidas en las clases istream, ostream e iostream. La funcin miembro width() establece la anchura de campo mnima para un dato de salida. Sus prototipos son: int width(int n); int width(); donde el valor de retorno es la anchura anterior n. La anchura establecida con la funcin width() es la mnima y siempre que sea necesario el sistema la aumenta de modo automtico. Esta anchura de campo slo es vlida para el siguiente dato que se imprime. Si se desea que siga siendo vlida hay que llamarla cada vez que se utiliza. La funcin miembro precision() establece el nmero de cifras para un dato de salida. Si no se indica nada la precisin por defecto es 6 dgitos. Los prototipos de la funcin precision() son: int precision(int n); int precision(); donde el valor de retorno es la precisin anterior n. La funcin miembro fill() establece el carcter de relleno para un dato de salida. Por defecto el carcter de relleno es el blanco ' '. Los prototipos de esta funcin son: char fill(char ch); char fill(); donde el valor de retorno es el carcter de relleno anterior n. Ejemplo: cout.width(10); //establece un ancho de campo de 10 cout.precision(2); //Establece la presicion de 2 cifras decimales cout.fill('-'); //Rellena con el carcter '-'. cout.setf(ios::right,ios::adjustfiel); //se alineara a la derecha. cout<<10/3; producir una salida en pantalla: 3.33

Manipuladores de entrada / salida


Los manipuladores son constantes y/o mtodos que constituyen una alternativa a los indicadores. Se pueden introducir en la propia sentencia de entrada o salida. Los manipuladores pueden tener argumentos o no tenerlos. Los manipuladores sin argumentos (endl, flush, etc.) estn definidos en iostream.h. Los que tienen argumentos estn declarados en iomanip.h. Un manipulador slo afecta al flujo (cin, cout, etc.) al que se aplica. El inconveniente de los manipuladores frente a los indicadores es que no permiten guardar la configuracin anterior y por tanto volver a ella de una forma general y sencilla.
CICLOII2012

Gua#1

UESFIAEIEPEL115

6/12

Los manipuladores de entrada / salida ms utilizados se citan a continuacin: dec, hex y oct: establecen base para enteros ws: se saltan los blancos iniciales endl: se imprime un '\n' y se vaca el buffer de salida flush: se vaca el buffer de salida setw(int w): establece la anchura mnima de campo setprecision(int p): establece el nmero de cifras setfill(char ch ): establece el carcter de relleno setiosflag(long i) equivale al indicador setf() unsetiosflag(long i) equivale a unsetf() Un manipulador se utiliza de la forma: cout << hex << 100; cout << setw(10) << mat[i][j] << endl; El efecto de los manipuladores permanece en el flujo correspondiente hasta que se cambian por otro manipulador, a excepcin de setw() que hay que introducirlo en el flujo antes de cada dato al que se le quiera aplicar esa anchura de campo.

Manejo de Archivos
Para poder leer desde o escribir en Archivos (lectura / escritura de datos en unidades de almacenamiento permanente como los disquetes, discos duros, etc.), se debe incluir la librera <fstream.h>. En esta librera se definen las clases necesarias para la utilizacin de Archivos, que son ifstream, ofstream y fstream. Antes de abrir un Archivo hay que crear un flujo, es decir un objeto de las clases ifstream, ofstream o fstream e indicar el modo de apertura (lectura, escritura, lectura y escritura, etc.). Los modos en los que se puede abrir un Archivo son: ios::append ios::in ios::out aadir datos al final del Archivo abrir Archivo para leer datos abrir Archivo para escribir datos

Por ejemplo para abrir un Archivo para lectura de datos creando un fstream Archivo: fstream Archivo; Archivo.open("datos.dat", ios::in); y para escritura en ese mismo Archivo: fstream Archivo; Archivo.open("datos.dat", ios::out); Las clases ifstream y ofstream tienen tambin constructores que permiten abrir Archivos de forma automtica ifstream Archivo("datos.dat"); donde se sobreentiende que el Archivo se abre para lectura por haber utilizado ifstream. Si se hubiese utilizado ofstream el Archivo se hubiera abierto para escritura.
CICLOII2012

Gua#1

UESFIAEIEPEL115

7/12

Funciones miembro de iostream


Las clases de entrada y salida de datos de C++ disponen de algunas funciones miembro que aumentan las capacidades de estas entradas y salidas. A continuacin se incluye la declaracin y una breve explicacin de las ms importantes: ostream& put(char c); ostream& write(const char* s, int n); istream& get(char& c); istream& get(char* s, int n, char c='\n'); Escribe un carcter en el flujo de salida Escribe n bytes de la cadena s en el flujo de salida. Puede utilizarse para salida binaria.. Lee un carcter del flujo de entrada y lo devuelve en el argumento pasado por referencia. Introduce en s a lo ms n caracteres del flujo de entrada (incluyendo el '\0') o hasta que encuentra el carcter de terminacin (por defecto '\n'), o el fin de Archivo. No retira el carcter de terminacin del flujo de entrada. Lee a lo ms n-1 caracteres del flujo de entrada o hasta que encuentra el carcter de terminacin (por defecto '\n') o hasta el fin de Archivo. Retira el carcter de terminacin del flujo de entrada, pero no lo almacena. Lee n bytes del flujo de entrada y los deposita en la cadena s. Se utiliza para entrada binaria. Ignora o descarta los n caracteres siguientes del flujo de entrada, o hasta que encuentra el carcter de terminacin (por defecto el fin de Archivo EOF). Devuelve el carcter c al flujo de entrada int peek(); lee un carcter del flujo de entrada pero sin retirarlo de dicho flujo; lo devuelve como valor de retorno. Devuelve el numero de bytes efectivamente ledos en la ultima llamada a read, getline o get.

istream& getline(char* s, int n, char c='\n');

istream& read(char* s, int n); istream& ignore(int n=1, int delim=EOF);

istream& putback(char c);

int gcount();

La mayor parte de las funciones anteriores devuelven una referencia al flujo de entrada o de salida. Como se ver un poco ms adelante, esta referencia puede utilizarse para detectar errores o la condicin de fin de Archivo. Para conocer con ms detalle cmo se utilizan ests funciones acudir a alguno de los textos de C++.

Funciones miembro de fstream


La clase fstream tiene algunas funciones miembro interesantes, tales como las siguientes: fstream(); constructor por defecto de la clase. Construye un flujo sin abrir ningn Archivo. El Archivo puede ser abierto ms tarde con la funcin open(). fstream(const char* filename, int nMode, int nProt = filebuf::openprot ); constructor general que crea un flujo al Archivo cuyo nombre se indica, del modo indicado (ios::in, ios::out, etc.),y con la proteccin indicada. La proteccin por defecto es filebuf::openprot, que equivale a filebuf::sh_compat, en MS-DOS. Otros posibles modos de proteccin son los siguientes: filebuf::sh_compat modo compatible (MS-DOS). filebuf::sh_none modo exclusivo - no se comparte. filebuf::sh_read se permite compartir para lectura. filebuf::sh_write se permite compartir para escritura. void open(const char* filename, int nMode, int nProt = filebuf::openprot ); funcin miembro que abre un Archivo en el modo y con la proteccin indicados. Sus argumentos son los mismos que los de fstream(). void close(); funcin miembro que cierra el Archivo asociado con un flujo sin destruir el flujo creado anteriormente.
CICLOII2012

Gua#1

UESFIAEIEPEL115

8/12

Errores de entrada / salida


Al leer y escribir de Archivos es frecuente que se produzcan errores, como por ejemplo no encontrar el Archivo o no poderlo abrir, o al menos situaciones de excepcin, tales como el haber llegado al fin del Archivo. Es importante saber cmo se pueden detectar estas situaciones con C++. La clase ios define una variable enum llamada io_state con los siguientes valores: goodbit, eofbit, badbit y failbit. Cada flujo de entrada/salida mantiene informacin sobre los errores que se hayan podido producir. Esta informacin se puede chequear con las siguientes funciones: int good (); devuelve un valor distinto de cero (true) si no ha habido errores (si todos los bits de error estn en off). int eof(); devuelve un valor distinto de cero si se ha llegado al fin del Archivo. int bad(); devuelve un valor distinto de cero si ha habido un error de E/S serio. No se puede continuar en esas condiciones. int fail(); devuelve un valor distinto de cero si ha habido cualquier error de E/S distinto de EOF. Si una llamada a bad() devuelve 0 (no error de ese tipo), el error puede no ser grave y la lectura puede proseguir despus de llamar a la funcin clear(). int clear(); se borran los bits de error que pueda haber activados. Adems, tanto los operadores sobrecargados (<< y >>) como las funciones miembro de E/S devuelven referencias al flujo correspondiente y esta referencia puede chequearse con un if o en la condicin de un while para saber si se ha producido un error o una condicin de fin de Archivo. Por ejemplo, las siguientes construcciones pueden utilizarse en C++: while (cin.get(ch)) s[i++]=ch; o bien, de una forma distinta, while (cin << ch) s[i++]=ch; ya que si el valor de retorno de (cin.get(ch)) o de (cin<<ch) no es nulo, es que no se ha producido error ni se ha llegado al fin de Archivo. Si lo que se quiere comprobar es si se ha llegado al final del archivo se puede comprobar la condicin, if (cin.get(ch).eof()) { // se ha llegado al final del Archivo } y si por el contrario lo que se desea es hacer algo si no se ha tenido ningn error, se puede utilizar el operador negacin () que devuelve un resultado distinto de cero (true) si failbit o badbit estn activados. if (cin.get(ch)) { // hay un error de tipo failbit o badbit. } El operador negacin se puede utilizar tambin en la forma siguiente, para saber si un Archivo se ha podido abrir correctamente: ifstream filein("datos.d"); if (filein) { cerr << "no se ha podido abrir el Archivo." << endl; exit(1); }

CICLOII2012

Gua#1

UESFIAEIEPEL115

9/12

EJEMPLOS.
Digite, compile y ejecute cada uno de los siguientes ejemplos.

EJEMPLO #1: IMPRESIN EN PANTALLA DE UNA MATRIZ ALEATORIA


#include<iostream.h> 1. #include<stdlib.h> 2. #include<iomanip.h> 3. #define FILAS 5 4. #define COLUMNAS 5 5. int main( ) 6. { 7. float matriz[FILAS][COLUMNAS]; //matriz de FILASxCOLUMNAS 8. for (int i=0;i<FILAS;i++) //llenar la matriz con numeros aleatorios 9. for (int j=0;j<COLUMNAS;j++) 10. matriz[i][j]=(rand( )-RAND_MAX/2.0)*1.23456789; 11. 12. cout.setf(ios::left|ios::scientific|ios::uppercase|ios::showpos); 13. //alineacion a la derecha, notacion cientfica, 14. // caracteres de formato en mayusculas, mostrar signo positivo 15. 16. for (int i=0;i<FILAS;i++) 17. { //imprimir la matriz 18. for (int j=0;j<COLUMNAS;j++) 19. { 20. cout <<setw(12) //ancho de campo 9 21. <<setprecision( 2 ) //precision 2 22. <<setfill(' ') //llenar con espacios 23. << matriz[i][j]; //imprimir el elemento 24. } 25. cout<<endl; 26. } 27. return 0; 28. }

EJEMPLO #2: PRESENTACIN EN PANTALA DE UN GRFICO.


/* Descripcion: Este programa muestra algo muy cercano a la grafica de la funcion seno trigonometrico. Por regla de tres se asigna cero caracteres al valor mas pequenho y 52 caracteres al valor mayor. */ 1. 2. 3. 4. 5. 6. 7. #include<iostream.h> #include<iomanip.h> #include<math.h> #include<values.h> #define NPUNTOS #define FUNCION(x) //cout,cin //setfill,setw //sin() //MAXFLOAT 69 sin(x)

CICLOII2012

Gua#1

UESFIAEIEPEL115

10/12

8. int main() 9. { 10. float x[NPUNTOS], y[NPUNTOS], 11. ymin=MAXFLOAT, ymax=-MAXFLOAT, 12. xmin, xmax; 13. cout<<"Introduzca el limite inferior de x: "; 14. cin>>xmin; 15. cout<<"Introduzca el limite superior de x: "; 16. cin>>xmax; 17. /*llenar vectores y determinar maximo y minimo de la funcion*/ 18. for (int i=0;i<NPUNTOS;i++) 19. { 20. x[i] = xmin+(xmax-xmin)/(NPUNTOS-1)*i; 21. y[i] = FUNCION(x[i]); 22. ymax = (y[i]>ymax) ? y[i]:ymax; 23. ymin = (y[i]<ymin) ? y[i]:ymin; 24. } 25. // alineacion a la derecha, formato en notacion cientifica, 26. // caracteres de formato en mayusculas y mostrar signo positivo 27. cout.setf(ios::right|ios::scientific|ios::uppercase|ios::showpos); 28. //escribir cabeceras 29. cout <<setfill(' ') 30. <<setw(6)<<"x" 31. <<setw(11)<<"f(x)" 32. <<setw(35)<<"grafico" 33. <<endl; 34. for (int i=0;i<NPUNTOS;i++) 35. { 36. cout<<'|'; 37. cout.width(9); //ancho de campo 9 38. cout.precision(2); //precision 2 39. cout.fill(' ');// llenar con blancos 40. cout<<x[i]<<'|'; 41. cout.width(9); //ancho de campo 9 42. cout.precision(2); //precision 2 43. cout.fill(' '); // llenar con blancos 44. cout<<y[i]<<'|'; 45. // el ancho del campo varia de acuerdo al valor de y[i] 46. // siendo 0 para y[i]=ymin y 52 cuando y[i]=ymax 47. cout.width( ( int ) 52 /(ymax-ymin)*(y[i]-ymin) ); 48. cout.fill(' '); // llenar con blancos 49. cout<<"*"<<endl; 50. } 51. return 0; 52. }

CICLOII2012

Gua#1

UESFIAEIEPEL115

11/12

EJEMPLO #3: LECTURA Y PRESENTACIN EN PANTALLA DE UN ARCHIVO.


/* Descripcion: Este programa es capaz de leer linea por linea todo el contenido de un archivo secuencial, cuando se presenta el fin de archivo, simplemente suspende la lectura. Observa que cada linea que se lee se impresa. */ 1. #include <fstream.h> 2. #include <iostream.h> 3. int main(int argc, char **argv){ 4. char frase[81]; 5. fstream fi; 6. if(argc != 2) { 7. cout << "Usar: verf <Archivo>"<< endl; 8. return 1; 9. } 10. fi.open(argv[1], ios::in); 11. if(!fi) { 12. cout << "El Archivo " << argv[1] 13. << " no existe o no puede ser abierto."<< endl; 14. return 1; 15. } 16. while(fi.getline( frase , 80 ) != NULL){ 17. cout << frase << endl; 18. } 19. return 0; 20. }

EJEMPLO #4: COPIA DE UN ARCHIVO


/* Descripcion: Este programa hace una copia de una archivo secuencia hacia otro archivo secuencial, mas abajo se muestra como compilar y comprobar el buen desempeo de este ejemplo*/ 1. #include <fstream.h> 2. #include <iostream.h> 3. #include <stdlib.h> 4. int main(int argc, char **argv){ 5. ifstream fe; 6. ofstream fs; 7. char buffer[2048]; // Buffer de 2 Kbytes 8. int bytesLeidos; 9. if(argc != 3){ 10. system("clear"); 11. cout << "Usar: copia <Archivo_origen> <Archivo_destino>" << endl; 12. return 1; 13. } 14. //abrir el archivo de entrada para lectura 15. fe . open( argv[1], ios::in ); 16. if( !fe ) { 17. system("clear"); 18. cout << "El Archivo " << argv[1] 19. << " no existe o no puede ser abierto."<< endl; 20. return 1; 21. }

CICLOII2012

Gua#1

UESFIAEIEPEL115

12/12

22. // Crear o sobreescribir el Archivo de salida 23. fs.open(argv[2], ios::out); 24. if( !fs ){ 25. cout << "El Archivo " << argv[2] << " no puede ser creado." << endl; 26. fe . close( ); 27. return 1; 28. } 29. // Bucle de copia: 30. do { 31. fe.read( buffer, 2048 ) ;//leer del archivo de entrada al buffer 32. //escribir el buffer en el archivo de salida 33. fs . write(buffer,fe.gcount()); 34. } while( !fe.eof( ) ); 35. // Cerrar Archivos: 36. fe . close( ); 37. fs . close( ); 38. return 0; 39. }

ASIGNACIONES
1- Realizar un programa que solicite un numero entero n entre 2 y 23 para que muestre un tringulo como el abajo que es para n=5 . 11 1212 123123 12351235 1235712357 2- Hacer un programa en C++ que acepte una oracin desde el teclado para luego imprimirla en un archivo en orden inverso. Se recomienda el uso de new y delete. 3- Hacer un programa en C++ que genere una matriz de nxn de nmeros aleatorios, y que guarde la matriz inversa correspondiente en algn archivo. Tanto 'n' como el nombre del archivo se pasar desde la lnea de comandos y, si el archivo existe se debe lanzar una advertencia con el fin de no hacer una sobre escritura. 4- Hacer un programa en C++ que escriba en un archivo mil nmeros enteros aleatorios. 5- El inventario de una tienda esta guardado en un archivo, en el cual cada producto utiliza los siguientes campos: cdigo de barras, nombre del producto, precio unitario y existencia. Hacer un programa en C++ que busque un producto en particular, y si esta en el inventario indicar toda la informacin relacionada con el. Desde la lnea de comando se pasar el nombre del producto y del archivo, si el nmero de parmetros no es adecuado se debe presentar un mensaje de error y si el producto no esta en el inventario se debe mostrar en pantalla '' Producto no encontrado '', si el archivo no existe se debe generar un beep y el mensaje ''Archivo no existe'' y si el archivo no se puede abrir se debe mostrar en pantalla '' Permiso denegado''.

CICLOII2012

También podría gustarte