PLE:Unidad7

=Entrada y Salida con ficheros= C++ nos proporciona un conjunto de clases que nos permiten la entrada y salida de datos desde y hacia ficheros. Concretamente disponemos de:


 * ofstream: Clase para la escritura de datos en ficheros
 * ifstream: Clase para la lectura de datos desde ficheros
 * fstream: Clase para la escritura/lectura de datos en ficheros.

=ofstream= Esta clase no proporciona un flujo de datos (stream) para escribir datos en un fichero Para crearnos un objeto de tipo stream basta declararlo como ofstream, tal como se muestra a continuación:

using namespace std;
 * 1) include
 * 2) include

void main {	ofstream fs; fs.open ("fichero.txt"); fs << "Escribiendo en un fichero mediante ofstream.\n"; fs.close; }

En este primer caso el stream no está conectado con un determinado fichero, por lo que deberemos conectarlo con posterioridad como veremos en la operación "open".

Por otro lado podemos declarar un stream de salida y conectarlo con un fichero determinada, tal como muestra el siguiente fragmento de código:

using namespace std;
 * 1) include
 * 2) include

void main {	ofstream fs("example.txt"); fs << "Escribiendo en un fichero mediante ofstream.\n"; fs.close; }

=ifstream= Esta clase no proporciona un flujo de datos (stream) para leer datos en un fichero Para crearnos un objeto de tipo stream basta declararlo como ifstream, tal como se muestra a continuación:

using namespace std;
 * 1) include
 * 2) include

void main {	ifstream fe; char cad[80]: fe.open ("fichero.txt"); // Leemos una linea desde el fichero de estrada fe >> cad; // Escribimos en pantalla cout << cad; fe.close; }

=Abriendo ficheros= La operación de apertura nos permite conectar un fichero determinado con un objeto "stream". Una vez llevada a cabo la operación de apertura, todoas las operaciones de entrada o salida se llevarán a cabo sobre el fichero al cual hemos conectado el stream.

open(nombreFichero, modeApertura);

Al llevar a cabo la llamada a la función miembro "open" debemos especificar el nombre del fichero y el modo de apertura a emplear. El modo de apertura es opcional y resulta la combinación de los valores mostrados en la siguiente tabla:

Los valores expuestos se pueden combinar mediante el operados OR "|".

ofstream fs; fs.open ("fichero.bin", ios::out | ios::app | ios::binary);

Abre el fichero en modo binario, para escritura y añadiendo escribiendo los datos al fical del mismo.

El modo de apertura por defecto va a depender del tipo de stream que estemos empleando. En el caso de un stream de salida (ofstrem) se asume el modo "ios::out".

Para comprobar que un stream asociado a un fichero se ha abierto correctamente podemos utilizar la función miembro "is_open" que nos devuelve un valor lógico que nos indica que la apertura se ha llevado a cabo correctamente.

using namespace std;
 * 1) include
 * 2) include

void main {	ofstream fs; fs.open ("example.txt"); if(fs.is_open) fs << "Escribiendo en un fichero mediante ofstream.\n"; else cout << "Error de apertura\n"; fs.close; }

=Cerrando ficheros= Una vez que hemos finalizado todas las operaciones de entrada o salida en fichero, este debe ser liberado mediante la operación "close".

fs.close;

Al llamar a esta función miembro, el objeto stream queda liberado y puede ser utilizado para acceder a otro fichero distinto. Además el fichero con el que estaba ligado el objeto stream puede ser abierto nuevamente por cualquier otro stream.

=Estado de un stream= Disponemos de una serie de funciones miembro que nos permiten testar el estado de un stream. Todoas estas funciones devuelven valores de tipo lógico.

using namespace std;
 * 1) include
 * 2) include

void main {	ifstream fe; char cad[80]: fe.open ("fichero.txt"); // Leemos una linea desde el fichero de estrada fe >> cad; while(!fe.eof) {		// Escribimos en pantalla cout << cad; // Leemos la siguiente linea fe >> cad; }	fe.close; }

=Entrada y salida de datos mediante streams= Para la lectura y escritura de datos en fichero podemos utilizar varios operadores y funciones miembro que conocemos sobradamente por que ya han dsido empleadas con "cin" y "cout". No obstante vamos a recordarlas y mostraremos alguna nueva.

Operador de salida <<
El operador de salida se encuentra sobrecargado para los tipos elementales de datos y funciona de igual modo que con el objeto "cout"

Operador de entrada >>
El operador de entrada se encuentra sobrecargado para los tipos elementales de datos y funciona de igual modo que con el objeto "cin"

Lectura mediante get
Permite la lectura de caracteres desde un stream de entrada. La función "get" se encuentra sobrecargado y contamos con las variantes mostradas a continución:

int get;				// Lee un caracter. Devuelve EOF si no hay disponible. istream& get(char*, int len, char = '\n'); // Lee una cadena con la longitud especificada istream& get(char&);			// Lee un caracter

Lectura con getline
Permite la lectura de una cadena de caracteres con un longitud especificada. Lee la cadena hasta que se encuentra el delimitador especificado, que por defecto es '\n'

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

ignore
Extrae del stream los siguientes "n" caracteres. Se detiene cuando encuentra el delimitador especificado.

istream& ignore(int n = 1, int delim = EOF);

peek
Nos devuelve el siquiente caracter del stream peron sin extraerlo.

int peek;

putback
Devuelve el caracter especificado al stream.

istream& putback(char);

Escritura con put
Escribe un carcater en un stream de salida.

ostream& put(char ch);

flush
Vacia el buffer del stream de salida, escribiendo todas las salidas pendientes.

ostream& flush;

=Lectura y escritura en ficheros binarios= Para la lectura o escritura sobre streams en formato binario empleamos las funciones read y write mostradas a continucación.

write
Permite la escritura de datos de un stream. Debemos pasarle un puntero a un caracter y especificarle el número de bytes a escribir.

ostream& write(const char*, int n);

Se puede utilizar para la escritura de cualquier tipo de datos, basta hacer la conversión a "char *".

using namespace std;
 * 1) include
 * 2) include

struct contacto {     char nombre[50]; char telefono[15];

};

void main {	contacto c;	ofstream fs("agenda.txt", ios::out | ios::binary);

if(fs.good) {		fs.write ((char *) c, sizeof(contacto)); fs.close; } }

Lectura de datos con read
Permite la lectura de datos de un stream, Debemos pasarle un puntero a un caracter y especificarle el número de bytes a leer. Esta función almacenará los datos en la posición especificada por el puntero.

istream& read(char*, int);

Se puede utilizar para la lectura de cualquier tipo de datos, basta hacer la conversión a "char *", tal como muestra el siguiente código:

using namespace std;
 * 1) include
 * 2) include

struct contacto {     char nombre[50]; char telefono[15];

};

void main {	contacto c;	ifstream fe ("agenda.txt", ios::in | ios::binary);

if(fe.is_open) {		fe.read ((char *) c, sizeof(contacto)); fe.close; } }

=Entrada y salida formateada= EL formato de la salida se puede cambiar mediante la manipulación de flags. Podemos emplear funciones específicas como: falgs, setf y unsetf. La manipulación de los flags tiene un efecto permanente y afecta a todas las entradas y salidas sucesivas.

Otro método para cambiar el formato de la entrada y salida es mediante el uso de unas funciones especiales denominadas manipuladores. Estas no tiene efecto permanente sobre el stream en cuestión. Para utilizar manipuladores debemos incluir el fichero de cabecera

Manipulador setw
Cambia la anchura de la salida indicando el número de caracteres a emplear.

using namespace std; void main {	int num = 23; ofstream fs("ejemplo.txt"); if(fs.good) {		fs << "#" << setw(6) << num << "#" << endl; fs.close; } }
 * 1) include
 * 2) include

Manipulador setbase
Cambia la base de numeración empleada en la salida. Admite como parámetro los valores 8, 10 y 16.

using namespace std; void main {	int num = 23; ofstream fs("ejemplo.txt"); if(fs.good) {		fs << "base 8 =" << setbase(8) << num; fs << "base 10 =" << setbase(10) << num; fs << "base 16 =" << setbase(16) << num <<endl; fs.close; } }
 * 1) include
 * 2) include

Manipulador setfill
Especifica el caracter de relleno utilizado en la salida. Este caracter de relleno se empleará en el caso de que la anchura requerida sea mayor que la necesaria.

using namespace std; void main {	int num = 23; ofstream fs("ejemplo.txt"); if(fs.good) {		fs << setfill('0') << num << endl; fs.close; } }
 * 1) include
 * 2) include

Manipulador setprecision
Podemos indicar el número de dígitos a utilizar en la salida para mostrar números reales.

using namespace std; void main {	float pi = 3.14159; ofstream fs("ejemplo.txt"); if(fs.good) {		fs << setprecision(3) << pi << endl; fs.close; } }
 * 1) include
 * 2) include

Manipuladores setiosflags y resetiosflags
Estas funciones permiten activar los flgas de formato de datos. Podemos especificar los siguientes:

Manipulador dec
Emplea formato decimal para la lectura o escritura de números.

Manipulador hex
Emplea formato hexadecimal para la lectura o escritura de números.

Manipulador oct
Emplea formato octal para la lectura o escritura de números.

Función fill
Especifica el caracter de relleno a utilizar en la salida

int num = 23; fs.width(10); fs.fill('%'); fs << "|" << num << "|" << endl;

Función precision
Cambia el numero de dígitos a mostrar en números reales.

Función setf
Permite activar/desactivar los flags de formato.

long setf(long);

Ejemplo: int num = 17; fs.setf(ios::left); fs << num;

Función unsetf
Permite desactivar los flags de formato.

void unsetf(long mascara);

Desactiva los flags que estén activos en el parámetro.

int num = 17; fs.unsetf(ios::left | ios::right | ios::internal); fs.setf(ios::left); fs.width(10); fs << num;

Función flags
Permite cambiar o leer los flags de manipulación de formato:

long flags const; 		// Devuelve el valor actual de los flags. long flags(long valor);

Ejemplo int num = 18; long f; f = flags; f |= ios::left; fs.flags(f); fs.width(10); fs << num;

=Ejercicios=
 * 1) Escribir varias lineas de texto en un fichero. Solución.
 * 2) Leer un fichero de texto y mostrarlo en pantalla.Solución.
 * 3) Contar la frecuencia de aparición de caracteres en un fichero de texto.Solución.
 * 4) Contar la frecuencia de aparición de palabras en un fichero de texto.Solución.
 * 5) Cifrar un fichero de texto mediante el método Cesar.Solución.
 * 6) Descifrar un fichero de texto mediante el método Cesar.Solución.
 * 7) Agregar a la agenda electrócia la opción de lectura y escritura en fichero
 * 8) Mini editor de texto.
 * 9) Editor hexadecimal
 * 10) Operaciones sobre ficheros "BMP"
 * 11) Editar etiquetas ID3
 * 12) Uso de una libreria de compresión de datos