Engineering">
Guia de Laboratorio 06
Guia de Laboratorio 06
Guia de Laboratorio 06
GUÍA DE LABORATORIO
PROGRAMACIÓN DE SISTEMAS
SEMESTRE A
COMPETENCIAS
Diseña responsablemente sistemas componentes o procesos para satisfacer necesidades dentro de restricciones
realistas, económicas, medio ambientales, sociales, políticas, éticas, de salud, de seguridad, manufacturación y
sostenibilidad
Construye responsablemente soluciones siguiendo un proceso adecuado llevando a cabo las pruebas ajustadas a
los recursos disponibles del cliente
Aplica la forma flexible técnicas, métodos, principios, normas, estándares y herramientas de ingeniería necesarias
para la construcción de software e implementación de sistemas de información
Curso: Programación de Sistemas Página: 1
Ficheros en C++
Laboratorio
6
I
OBJETIVOS
• La presente práctica de laboratorio tiene como objetivo trabajar con ficheros en C++
II
TEMAS A TRATAR
• Trabajar con Ficheros.
• Crear un Fichero de Salida.
• Ficheros Binarios.
• Ficheros de Acceso Aleatorio.
• Ficheros de Entrada y Salida.
III
MARCO TEÓRICO
❖ TRABAJAR CON FICHEROS:
Los archivos o ficheros son la forma en la que C++ permite el acceso al disco. Todos
los procesos tienen abiertos, por defecto, los archivos 0(entrada), 1(salida) y 2(salida
de errores), de manera que en C++ se corresponden con los objetos cin, cout y cerr.
De estos últimos, el primero pertenece a la clase ifstream, que a su vez desciende de
istream (flujo de entrada). Los dos últimos pertenecen a la clase ofstream, que
desciende de la clase ostream (flujo de salida). Una jerarquía aproximada puede verse
a continuación.
Usar streams facilita mucho el acceso a ficheros en disco, veremos que una vez que
creemos un stream para un fichero, podremos trabajar con él igual que lo hacemos con
cin o cout.
Mediante las clases ofstream, ifstream y fstream tendremos acceso a todas las
funciones de las clases base de las que se derivan estas: ios, istream, ostream,
fstreambase, y como también contienen un objeto filebuf, podremos acceder a las
funciones de filebuf y streambuf.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
char cadena[128];
// Crea un fichero de salida
ofstream fs("nombre.txt");
return 0;
}
Veamos otro ejemplo sencillo, para ilustrar algunas limitaciones del operador >> para
hacer lecturas, cuando no queremos perder caracteres.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
char cadena[128];
ifstream fe("streams.cpp");
while(!fe.eof()) {
fe >> cadena;
cout << cadena << endl;
}
fe.close();
return 0;
}
El resultado quizá no sea el esperado. El motivo es que el operador >> interpreta los
espacios, tabuladores y retornos de línea como separadores, y los elimina de la cadena
de entrada.
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 4
❖ FICHEROS BINARIOS:
Los ficheros binarios son más útiles para guardar información cuyos valores no estén
limitados. Por ejemplo, para almacenar imágenes, o bases de datos. Un fichero binario
permite almacenar estructuras completas, en las que se mezclen datos de cadenas con
datos numéricos.
En realidad, no hay nada que nos impida almacenar cualquier valor en un fichero de
texto, el problema surge cuando se almacena el valor que el sistema operativo usa
para marcar el fin de fichero en un archivo de texto. En MS-DOS ese valor es 0x1A.
Si abrimos un fichero en modo de texto que contenga un dato con ese valor, no nos
será posible leer ningún dato a partir de esa posición. Si lo abrimos en modo binario,
ese problema no existirá.
Los ficheros que hemos usado en los ejemplos anteriores son en modo texto, veremos
ahora un ejemplo en modo binario:
#include <iostream>
#include <fstream>
#include <cstring>
struct tipoRegistro {
char nombre[32];
int edad;
float altura;
};
int main() {
tipoRegistro pepe;
tipoRegistro pepe2;
ofstream fsalida("prueba.dat",
ios::out | ios::binary);
fsalida.write(reinterpret_cast<char *>(&pepe),
sizeof(tipoRegistro));
fsalida.close();
ifstream fentrada("prueba.dat",
ios::in | ios::binary);
fentrada.read(reinterpret_cast<char *>(&pepe2),
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 5
sizeof(tipoRegistro));
cout << pepe2.nombre << endl;
cout << pepe2.edad << endl;
cout << pepe2.altura << endl;
fentrada.close();
return 0;
}
Otro par de funciones relacionadas con el acceso aleatorio son tellp y tellg, que sirven
para saber en qué posición del fichero nos encontramos.
#include <fstream>
using namespace std;
int main() {
int i;
char mes[][20] = {"Enero", "Febrero", "Marzo",
"Abril", "Mayo", "Junio", "Julio", "Agosto",
"Septiembre", "Octubre", "Noviembre",
"Diciembre"};
char cad[20];
ofstream fsalida("meses.dat",
ios::out | ios::binary);
// Acceso secuencial:
cout << "\nAcceso secuencial:" << endl;
fentrada.read(cad, 20);
do {
cout << cad << endl;
fentrada.read(cad, 20);
} while(!fentrada.eof());
fentrada.clear();
// Acceso aleatorio:
cout << "\nAcceso aleatorio:" << endl;
for(i = 11; i >= 0; i--) {
fentrada.seekg(20*i, ios::beg);
fentrada.read(cad, 20);
cout << cad << endl;
}
return 0;
}
La función seekg nos permite acceder a cualquier punto del fichero, no tiene por qué
ser exactamente al principio de un registro, la resolución de las funciones seek es de
un byte.
Cuando trabajemos con nuestros propios streams para nuestras clases, derivándolas de
ifstream, ofstream o fstream, es posible que nos convenga sobrecargar las funciones
seek y tell para que trabajen a nivel de registro, en lugar de hacerlo a nivel de byte.
Para eso usaremos la clase fstream, que al ser derivada de ifstream y ofstream,
dispone de todas las funciones necesarias para realizar cualquier operación de entrada
o salida.
Hay que tener la precaución de usar la opción ios::trunc de modo que el fichero sea
creado si no existe previamente.
Este programa crea un fichero con una palabra, a continuación, lee todo el fichero y
cambia todos los caracteres 'a' por 'e'. Finalmente muestra el resultado. Básicamente
muestra cómo trabajar con ficheros simultáneamente en entrada y salida.
#include <fstream>
using namespace std;
int main() {
char l;
long i, lon;
fstream fich("prueba.dat", ios::in |
ios::out | ios::trunc | ios::binary);
fich.seekg(0L, ios::end);
lon = fich.tellg();
for(i = 0L; i < lon; i++) {
fich.seekg(i, ios::beg);
fich.get(l);
if(l == 'a') {
fich.seekp(i, ios::beg);
fich << 'e';
}
}
cout << "Salida:" << endl;
fich.seekg(0L, ios::beg);
for(i = 0L; i < lon; i++) {
fich.get(l);
cout << l;
}
cout << endl;
fich.close();
return 0;
}
IV
ACTIVIDADES
• Consideraciones: Instalar un IDE para la programación de C++. Puede ser Zinjal,
Visual Studio 2019, entre otros.
• ACTIVIDAD 2.
• ACTIVIDAD 3.
V
EJERCICIOS RESUELTOS
• EJERCICIO 01
Utilizando un programa en C++. escribir una frase en un fichero de texto, la cual
es "Texto para el fichero" en un archivo "ficheroTexto.txt”
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream ficheroSalida;
ficheroSalida.open ("ficheroTexto.txt");
ficheroSalida << "Texto para el fichero";
ficheroSalida.close();
return 0;
}
• EJERCICIO 02
Crear un programa en C++ y leer una línea de un fichero usando ifstream y usando
la función getline
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 9
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream ficheroEntrada;
string frase;
ficheroEntrada.open ("ficheroTexto.txt");
getline(ficheroEntrada, frase);
ficheroEntrada.close();
return 0;
• EJERCICIO 03
Crear un programa en C++ que pudiera leer cualquier archivo indicado por el
usuario y lo mostrara por pantalla, en caso de no existir dicho archivo mostrar el
mensaje "Fichero inexistente o faltan permisos para abrirlo"
#include <iostream>
#include <fstream>
int main () {
fstream ficheroEntrada;
string nombre;
string frase;
while (! ficheroEntrada.eof() ) {
getline (ficheroEntrada,frase);
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 10
ficheroEntrada.close();
}
else cout << "Fichero inexistente o faltan permisos para abrirlo" << endl;
return 0;
}
• EJERCICIO 04
Utilizando un programa en C++, crear un archivo que escriba las frases: "Esto es
una línea", en otra línea escribir: "Esto es otra" y finalmente escribir: " y esto es
continuación de la anterior" en un archivo llamado "prueba.txt"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream fichero("prueba.txt");
fichero << "Esto es una línea" << endl;
fichero << "Esto es otra";
fichero << " y esto es continuación de la anterior" << endl;
fichero.close();
return 0;
}
• EJERCICIO 05
Crear un archivo en C++ que permita leer las líneas del archivo “prueba.txt”
creado en el ejercicio anterior utilizando la función ifstream
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fichero("prueba.txt");
string linea;
fichero.close();
return 0;
}
• EJERCICIO 06
Crear un archivo en C++ que permita leer toda una línea del archivo cuyo nombre
es ingresado como argumento
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
cout << "Dime el nombre del fichero: ";
string nombre;
getline(cin, nombre);
ifstream fichero(nombre.c_str());
string linea;
getline(fichero,linea);
cout << "Se ha leido: " << endl;
cout << linea << endl;
fichero.close();
return 0;
}
• EJERCICIO 07
Crear un programa en C++ que permita leer un fichero desde su inicio hasta el
final, utilizando la función eof() del fichero en caso de no encontrarse el fichero
deseado por el usuario mostrar el mensaje "No existe el fichero!"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 12
string nombre;
string linea;
ifstream fichero(nombre.c_str());
if( fichero.fail() )
{
cout << "No existe el fichero!" << endl;
exit(1);
}
while (! fichero.eof())
{
getline(fichero,linea);
if (! fichero.eof())
cout << linea << endl;
}
fichero.close();
return 0;
}
• EJERCICIO 08
Crear un programa en C++ y utilizando la función getline y la función eof,
averiguar si un fichero tiene contenido
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
string nombre;
string linea;
ifstream fichero(nombre.c_str());
if( fichero.fail() )
{
cout << "No existe el fichero!" << endl;
exit(1);
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 13
}
if(! fichero.eof() )
{
getline(fichero,linea);
if(linea == "")
cout << "fichero vacío" << endl;
exit(1);
}
cout << "el fichero tiene contenido" << endl;
fichero.close();
return 0;
}
• EJERCICIO 09
Crear un programa en C++ y utilizando la funcion read y seek, abrir un fichero y
comprobar que tiene el contenido de una imagen BMP
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
string nombre;
char datos[256];
int compresion;
if ( fichero.fail() )
cout << "No encontrado" << endl;
else
{
fichero.seekg(30, fichero.beg);
fichero.read(datos,1);
fichero.close();
compresion = datos[0];
if (compresion == 0)
cout << "Sin compresión";
else
cout << "BMP Comprimido";
}
return 0;
}
• EJERCICIO 10
Crear un archivo en c++ que permita el acceso aleatorio a un archivo meses.dat
que almacena los nombres de los meses
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int i;
char mes[][20] = {"Enero", "Febrero", "Marzo",
"Abril", "Mayo", "Junio", "Julio", "Agosto",
"Septiembre", "Octubre", "Noviembre",
"Diciembre"};
char cad[20];
ofstream fsalida("meses.dat",
ios::out | ios::binary);
// Acceso secuencial:
cout << "\nAcceso secuencial:" << endl;
fentrada.read(cad, 20);
do {
cout << cad << endl;
fentrada.read(cad, 20);
} while(!fentrada.eof());
fentrada.clear();
// Acceso aleatorio:
cout << "\nAcceso aleatorio:" << endl;
for(i = 11; i >= 0; i--) {
fentrada.seekg(20*i, ios::beg);
fentrada.read(cad, 20);
cout << cad << endl;
}
return 0;
}
• EJERCICIO 11
Crear un programa en C++ que cree un fichero con una palabra, mientras lee
cambia los caracteres de 'a' por 'e'
#include <fstream>
#include <iostream>
using namespace std;
int main() {
char l;
long i, lon;
fstream fich("prueba.dat", ios::in |
ios::out | ios::trunc | ios::binary);
fich.seekg(0L, ios::end);
lon = fich.tellg();
for(i = 0L; i < lon; i++) {
fich.seekg(i, ios::beg);
fich.get(l);
if(l == 'a') {
fich.seekp(i, ios::beg);
fich << 'e';
}
}
cout << "Salida:" << endl;
fich.seekg(0L, ios::beg);
for(i = 0L; i < lon; i++) {
fich.get(l);
cout << l;
}
cout << endl;
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 16
fich.close();
return 0;
}
VI
EJERCICIOS PROPUESTOS
Nota: Para los siguientes ejercicios, programar de forma ordenada de tal manera que
las clases y/o estructuras queden definidas en archivos cabecera (.h), los métodos u
operaciones en un archivo .cpp y finalmente el programa principal en otro archivo
.cpp. Asimismo, debe utilizar la experiencia de la práctica anterior y debe estar visible
en el código.
• EJERCICIOS PROPUESTOS:
struct Tdato
{
int b;
char s[100];
};
int x, n, a[10]={1,2,3,4,5,6,7,8,9,0};
double f;
char nombre[]="Ejercicios ficheros binarios";
Tdato p;
ifstream f1;
ofstream f2;
f1.open("entrada.dat", ios::binary);
f2.open("salida.dat", ios::binary);
Escribe las instrucciones para realizar cada una de las siguientes operaciones:
a. Escribir el dato entero x en el fichero.
b. Escribir el dato double f en el fichero.
c. Escribir los 5 primeros elementos del array a en el fichero.
d. Escribir los 10 primeros caracteres de la cadena nombre en el fichero.
e. Escribir el dato de tipo Tdato p en el fichero.
f. Leer un dato entero del fichero y almacenarlo en la variable x.
g. Leer un dato double del fichero y almacenarlo en la variable f.
h. Leer 5 enteros y almacenarlos en el array a.
i. Leer 10 caracteres y almacenarlos en la cadena nombre.
3. Crear un programa que pida al usuario que teclee frases, y las almacene en el
fichero “frases.txt”. Acabará cuando el usuario pulse Intro sin teclear nada.
Después deberá mostrar el contenido del fichero.
5. Crear una agenda que maneje los siguientes datos: nombre, dirección, tlf
móvil, email, y día, mes y año de nacimiento (estos tres últimos datos deberán
ser números enteros cortos). Deberá tener capacidad para 100 fichas. Se deberá
poder añadir un dato nuevo, visualizar los nombres de las fichas existentes, o
mostrar todos los datos de una persona (se preguntará al usuario cual es el
nombre de esa persona que quiere visualizar). Al empezar el programa, leerá
los datos de un fichero llamado “agenda.dat” (si existe). Al terminar, guardará
todos los datos en ese fichero.
NOTA: No son hache intercalada las que son comienzo de palabra ni las que
aparecen formando 'ch'.
9. Crea un programa que cuente las palabras que hay en un archivo de texto.
NOTA: Escribe una función o una macro que te indique si un carácter es una
letra o no. No utilices una función estándar que hay para ello.
10. Escriba un programa que haga una lista de todas las palabras encontradas en
un archivo de entrada y escriba esa lista en un archivo de salida, junto con el
número de veces que ha aparecido cada palabra.
11. Se dispone de dos ficheros de texto que contienen una lista de números enteros
cada uno, ordenados de menor a mayor, a razón de un número por línea. Se
pide un programa en C que a partir de estos dos ficheros, genere un tercer
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 18
fichero que contenga todos y cada uno de los datos de los dos ficheros iniciales
y esté también ordenado de menor a mayor.
12. Escriba un programa que lea un fichero de texto con varias líneas y cuente
cuantas vocales hay de cada tipo (a,e,i,o,u). NOTA: Para almacenar el número
de vocales usar un array de 5 posiciones.
VII
CUESTIONARIO
1. ¿Es necesario tener una función para cerrar un archivo?
2. ¿Cuántos tipos de permisos tienen los archivos en un sistema operativo basado en una
distribución Linux?
VIII
BIBLIOGRAFÍA
[1] P.J. Deitel and H.M. Deitel, “Cómo Programar en C++”, México, Ed. Pearson
Educación, 2009
[2] B. Stroustrup, “El Lenguaje de Programación C++”, Madrid, Adisson Pearson
Educación, 2002
[3] B. Eckel, “Thinking in C++”, Prentice Hall, 2000