Introducción
En este laboratorio, aprenderá a realizar diversas operaciones de archivos en C++. El laboratorio cubre la apertura de archivos para lectura y escritura, la escritura de datos de texto en archivos, la lectura de datos desde archivos de texto, la comprobación del estado de apertura del archivo, el manejo de errores de lectura/escritura de archivos, el trabajo con archivos binarios, el posicionamiento del puntero de archivo y el cierre de archivos para liberar recursos. Obtendrá experiencia práctica en el uso de las clases fundamentales de flujo de archivos ofstream e ifstream de la biblioteca estándar de C++ para interactuar con archivos. Al finalizar este laboratorio, tendrá una comprensión sólida del manejo de archivos en la programación C++.
Abrir Archivos Usando ofstream e ifstream
En este paso, aprenderá a abrir archivos en C++ utilizando dos clases fundamentales de flujo de archivos: ofstream para escribir archivos e ifstream para leer archivos. Estas clases son parte de la biblioteca estándar de C++ y proporcionan capacidades esenciales para el manejo de archivos.
Primero, navegue al directorio del proyecto en la terminal del WebIDE:
cd ~/project
Cree un nuevo archivo C++ llamado file_operations.cpp:
touch file_operations.cpp
Agregue el siguiente código al archivo file_operations.cpp:
#include <iostream>
#include <fstream> // Incluir la cabecera de flujo de archivos
int main() {
// Apertura de un archivo para escritura usando ofstream
std::ofstream outputFile("example.txt");
// Comprobar si el archivo se abrió con éxito
if (outputFile.is_open()) {
std::cout << "File opened for writing successfully!" << std::endl;
outputFile.close(); // Cerrar el archivo
} else {
std::cout << "Unable to open file for writing." << std::endl;
}
// Apertura de un archivo para lectura usando ifstream
std::ifstream inputFile("example.txt");
// Comprobar si el archivo se abrió con éxito
if (inputFile.is_open()) {
std::cout << "File opened for reading successfully!" << std::endl;
inputFile.close(); // Cerrar el archivo
} else {
std::cout << "Unable to open file for reading." << std::endl;
}
return 0;
}
Analicemos los conceptos clave:
#include <fstream>: Incluye la biblioteca de flujo de archivos (file stream library)std::ofstream: Flujo de archivo de salida (Output file stream) para escribir archivosstd::ifstream: Flujo de archivo de entrada (Input file stream) para leer archivosis_open(): Comprueba si el archivo se abrió correctamenteclose(): Cierra el archivo después de las operaciones
Compile el programa:
g++ file_operations.cpp -o file_operations
Ejecute el ejecutable:
./file_operations
Salida de ejemplo:
File opened for writing successfully!
File opened for reading successfully!
Algunos puntos importantes sobre los flujos de archivos (file streams):
- Siempre compruebe si un archivo se abrió correctamente antes de realizar operaciones
- Recuerde cerrar los archivos después de terminar de usarlos
ofstreamse utiliza para escribir en archivosifstreamse utiliza para leer desde archivos- Ambas clases son parte de la cabecera
<fstream>
Puede pensar en los flujos de archivos como abrir y cerrar puertas a los archivos. ofstream le permite escribir en una habitación, mientras que ifstream le permite leer lo que hay dentro.
Escribir Datos de Texto en Archivos
En este paso, aprenderá a escribir datos de texto en archivos utilizando la clase ofstream en C++. Basándose en el paso anterior, explorará diferentes formas de escribir cadenas (strings), números y múltiples líneas en archivos.
Cree un nuevo archivo C++ llamado write_files.cpp:
touch ~/project/write_files.cpp
Agregue el siguiente código al archivo write_files.cpp:
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Abrir un archivo para escritura
std::ofstream outputFile("student_data.txt");
// Comprobar si el archivo se abrió con éxito
if (outputFile.is_open()) {
// Escribir una cadena simple
outputFile << "John Doe" << std::endl;
// Escribir múltiples piezas de datos
std::string name = "Alice Smith";
int age = 22;
double gpa = 3.75;
outputFile << name << ", " << age << " years old, GPA: " << gpa << std::endl;
// Escribir múltiples líneas
outputFile << "Computer Science Student" << std::endl;
outputFile << "University of Programming" << std::endl;
// Cerrar el archivo
outputFile.close();
std::cout << "Data written to file successfully!" << std::endl;
} else {
std::cout << "Unable to open file for writing." << std::endl;
}
return 0;
}
Compile el programa:
g++ write_files.cpp -o write_files
Ejecute el ejecutable:
./write_files
Salida de ejemplo:
Data written to file successfully!
Verifique el contenido del archivo:
cat student_data.txt
Contenido de ejemplo del archivo:
John Doe
Alice Smith, 22 years old, GPA: 3.75
Computer Science Student
University of Programming
Puntos clave sobre la escritura en archivos:
- Use el operador
<<para escribir datos en los archivos std::endlañade una nueva línea- Se pueden escribir cadenas (strings), números y variables
- Siempre compruebe si el archivo está abierto antes de escribir
- Cierre el archivo después de las operaciones de escritura
Puede pensar en escribir en archivos como escribir en un cuaderno. El ofstream es su bolígrafo, y el archivo es la página donde registra la información.
Leer Datos de Archivos de Texto
En este paso, aprenderá a leer datos de archivos de texto utilizando la clase ifstream en C++. Basándose en los pasos anteriores, explorará diferentes métodos para leer líneas, palabras y archivos completos.
Cree un nuevo archivo C++ llamado read_files.cpp:
touch ~/project/read_files.cpp
Agregue el siguiente código al archivo read_files.cpp:
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Abrir el archivo creado en el paso anterior
std::ifstream inputFile("student_data.txt");
// Comprobar si el archivo se abrió con éxito
if (inputFile.is_open()) {
// Leer línea completa
std::string line;
std::cout << "Reading entire lines:" << std::endl;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
// Restablecer el puntero del archivo al inicio
inputFile.clear();
inputFile.seekg(0, std::ios::beg);
// Leer palabras individuales
std::cout << "\nReading individual words:" << std::endl;
std::string word;
while (inputFile >> word) {
std::cout << word << " ";
}
std::cout << std::endl;
// Cerrar el archivo
inputFile.close();
} else {
std::cout << "Unable to open file for reading." << std::endl;
}
return 0;
}
Compile el programa:
g++ read_files.cpp -o read_files
Ejecute el ejecutable:
./read_files
Salida de ejemplo:
Reading entire lines:
John Doe
Alice Smith, 22 years old, GPA: 3.75
Computer Science Student
University of Programming
Reading individual words:
John Doe Alice Smith, 22 years old, GPA: 3.75 Computer Science Student University of Programming
Puntos clave sobre la lectura de archivos:
- Use
std::getline()para leer líneas completas - Use el operador
>>para leer palabras individuales clear()yseekg()restablecen el puntero del archivo- Siempre compruebe si el archivo está abierto antes de leer
- Cierre el archivo después de las operaciones de lectura
Puede pensar en leer archivos como extraer información de un libro. El ifstream es su marcador de posición, ayudándole a navegar por el texto.
Comprobar Estado de Apertura del Archivo
En este paso, aprenderá a verificar el estado de las operaciones de archivo en C++ utilizando varios métodos para verificar si los archivos se abrieron con éxito y están listos para leer o escribir.
Cree un nuevo archivo C++ llamado file_status.cpp:
touch ~/project/file_status.cpp
Agregue el siguiente código al archivo file_status.cpp:
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Intentar abrir un archivo existente para lectura
std::ifstream inputFile("student_data.txt");
// Método 1: Usar is_open() para comprobar el estado del archivo
if (inputFile.is_open()) {
std::cout << "File opened successfully for reading." << std::endl;
// Realizar operaciones de lectura
std::string line;
while (std::getline(inputFile, line)) {
std::cout << "Read line: " << line << std::endl;
}
inputFile.close();
} else {
std::cout << "Failed to open file for reading." << std::endl;
}
// Método 2: Usar good() para comprobar el estado del archivo
std::ofstream outputFile("test_status.txt");
if (outputFile.good()) {
std::cout << "File opened successfully for writing." << std::endl;
outputFile << "Testing file status" << std::endl;
// Comprobaciones de estado adicionales
if (outputFile) {
std::cout << "File is in a good state for writing." << std::endl;
}
outputFile.close();
} else {
std::cout << "Failed to open file for writing." << std::endl;
}
// Método 3: Múltiples métodos de comprobación de estado
std::ifstream checkFile("non_existent_file.txt");
std::cout << "File status checks:" << std::endl;
std::cout << "is_open(): " << (checkFile.is_open() ? "True" : "False") << std::endl;
std::cout << "good(): " << (checkFile.good() ? "True" : "False") << std::endl;
std::cout << "fail(): " << (checkFile.fail() ? "True" : "False") << std::endl;
return 0;
}
Compile el programa:
g++ file_status.cpp -o file_status
Ejecute el ejecutable:
./file_status
Salida de ejemplo:
File opened successfully for reading.
Read line: John Doe
Read line: Alice Smith, 22 years old, GPA: 3.75
Read line: Computer Science Student
Read line: University of Programming
File opened successfully for writing.
File is in a good state for writing.
File status checks:
is_open(): False
good(): False
fail(): True
Puntos clave sobre la comprobación del estado del archivo:
is_open(): Comprueba si el archivo se abrió con éxitogood(): Comprueba si no ha ocurrido ningún errorfail(): Comprueba si ha ocurrido un error- Siempre compruebe el estado del archivo antes de realizar operaciones
- Diferentes métodos proporcionan varias formas de verificar el estado del archivo
Puede pensar en las comprobaciones de estado de archivo como una inspección de seguridad antes de un viaje. Estos métodos ayudan a garantizar que sus operaciones de archivo sean seguras y exitosas.
Manejar Errores de Lectura/Escritura de Archivos
En este paso, aprenderá a manejar posibles errores que pueden ocurrir durante las operaciones de lectura y escritura de archivos en C++. Comprender el manejo de errores es crucial para crear programas robustos de manipulación de archivos.
Cree un nuevo archivo C++ llamado file_error_handling.cpp:
touch ~/project/file_error_handling.cpp
Agregue el siguiente código al archivo file_error_handling.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
void writeToFile(const std::string& filename) {
std::ofstream outputFile(filename);
// Comprobar si el archivo está abierto
if (!outputFile) {
// Lanzar una excepción si el archivo no se puede abrir
throw std::runtime_error("Unable to open file for writing: " + filename);
}
try {
// Intentar escribir datos
outputFile << "Hello, Error Handling!" << std::endl;
outputFile << "This is a sample text." << std::endl;
// Simular un error de escritura (intencionalmente no recomendado)
if (outputFile.bad()) {
throw std::runtime_error("Write operation failed");
}
}
catch (const std::exception& e) {
std::cerr << "Error during writing: " << e.what() << std::endl;
}
outputFile.close();
}
void readFromFile(const std::string& filename) {
std::ifstream inputFile(filename);
std::string line;
// Comprobar si el archivo está abierto
if (!inputFile) {
// Lanzar una excepción si el archivo no se puede abrir
throw std::runtime_error("Unable to open file for reading: " + filename);
}
try {
// Leer e imprimir el contenido del archivo
std::cout << "File contents:" << std::endl;
while (std::getline(inputFile, line)) {
std::cout << line << std::endl;
}
// Comprobar si hay errores de lectura
if (inputFile.bad()) {
throw std::runtime_error("Read operation encountered an error");
}
}
catch (const std::exception& e) {
std::cerr << "Error during reading: " << e.what() << std::endl;
}
inputFile.close();
}
int main() {
try {
// Escribir en un archivo
writeToFile("error_handling_example.txt");
// Leer desde el archivo
readFromFile("error_handling_example.txt");
// Intentar leer desde un archivo inexistente
readFromFile("non_existent_file.txt");
}
catch (const std::exception& e) {
std::cerr << "Main error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Compile el programa:
g++ file_error_handling.cpp -o file_error_handling
Ejecute el ejecutable:
./file_error_handling
Salida de ejemplo:
File contents:
Hello, Error Handling!
This is a sample text.
Error during reading: Unable to open file for reading: non_existent_file.txt
Puntos clave sobre el manejo de errores de archivos:
- Use bloques
try-catchpara manejar posibles excepciones - Compruebe el estado del flujo de archivo antes y después de las operaciones
- Use
std::runtime_errorpara lanzar mensajes de error significativos - Maneje diferentes tipos de errores relacionados con archivos
- Proporcione mensajes de error informativos
Puede pensar en el manejo de errores como una red de seguridad. Atrapa problemas potenciales y evita que su programa falle inesperadamente.
Trabajar con Archivos Binarios Usando fstream
En este paso, aprenderá a trabajar con archivos binarios utilizando la clase fstream en C++. Los archivos binarios almacenan datos en su formato binario puro, lo cual es diferente de los archivos de texto y útil para almacenar datos estructurados de manera eficiente.
Cree un nuevo archivo C++ llamado binary_files.cpp:
touch ~/project/binary_files.cpp
Agregue el siguiente código al archivo binary_files.cpp:
#include <iostream>
#include <fstream>
#include <string>
// Estructura simple para demostrar la escritura en archivos binarios
struct Student {
int id;
char name[50];
double gpa;
};
void writeBinaryFile() {
std::fstream binaryFile("students.bin", std::ios::out | std::ios::binary);
if (!binaryFile) {
std::cerr << "Error opening file for writing!" << std::endl;
return;
}
// Crear algunos registros de estudiantes
Student students[3] = {
{1, "John Doe", 3.5},
{2, "Alice Smith", 3.8},
{3, "Bob Johnson", 3.2}
};
// Escribir la estructura completa en el archivo binario
binaryFile.write(reinterpret_cast<char*>(students), sizeof(students));
binaryFile.close();
std::cout << "Binary file written successfully!" << std::endl;
}
void readBinaryFile() {
std::fstream binaryFile("students.bin", std::ios::in | std::ios::binary);
if (!binaryFile) {
std::cerr << "Error opening file for reading!" << std::endl;
return;
}
Student students[3];
// Leer la estructura completa desde el archivo binario
binaryFile.read(reinterpret_cast<char*>(students), sizeof(students));
std::cout << "Student Records:" << std::endl;
for (int i = 0; i < 3; ++i) {
std::cout << "ID: " << students[i].id
<< ", Name: " << students[i].name
<< ", GPA: " << students[i].gpa << std::endl;
}
binaryFile.close();
}
int main() {
// Escribir archivo binario
writeBinaryFile();
// Leer archivo binario
readBinaryFile();
return 0;
}
Compile el programa:
g++ binary_files.cpp -o binary_files
Ejecute el ejecutable:
./binary_files
Salida de ejemplo:
Binary file written successfully!
Student Records:
ID: 1, Name: John Doe, GPA: 3.5
ID: 2, Name: Alice Smith, GPA: 3.8
ID: 3, Name: Bob Johnson, GPA: 3.2
Puntos clave sobre los archivos binarios:
- Use el indicador
std::ios::binarypara el modo binario - Métodos
write()yread()para datos binarios - Se utiliza
reinterpret_castpara convertir entre tipos - Útil para almacenar datos estructurados de manera eficiente
- Conserva la representación binaria exacta de los datos
Puede pensar en los archivos binarios como un plano preciso. Almacenan los datos exactamente como existen en la memoria, sin ninguna conversión de texto.
Posicionar Puntero de Archivo con seekg/seekp
En este paso, aprenderá a manipular los punteros de archivo usando seekg() para la lectura y seekp() para la escritura en C++. Estos métodos le permiten navegar y modificar posiciones específicas dentro de un archivo.
Cree un nuevo archivo C++ llamado file_pointer.cpp:
touch ~/project/file_pointer.cpp
Agregue el siguiente código al archivo file_pointer.cpp:
#include <iostream>
#include <fstream>
#include <string>
void createSampleFile() {
std::ofstream file("numbers.txt");
for (int i = 1; i <= 10; ++i) {
file << i << " ";
}
file.close();
}
void demonstrateSeekOperations() {
// Abrir archivo en modo lectura y escritura
std::fstream file("numbers.txt", std::ios::in | std::ios::out);
if (!file) {
std::cerr << "Error opening file!" << std::endl;
return;
}
// Lectura desde diferentes posiciones
std::cout << "Reading operations:" << std::endl;
// Mover al 5to byte (posición del carácter)
file.seekg(5);
int value;
file >> value;
std::cout << "Value at 5th byte: " << value << std::endl;
// Mover al principio del archivo
file.seekg(0);
file >> value;
std::cout << "First value: " << value << std::endl;
// Escritura en posiciones específicas
std::cout << "\nWriting operations:" << std::endl;
// Mover a una posición específica y escribir
file.seekp(0);
file << "100 ";
// Restablecer el puntero del archivo y leer para verificar
file.seekg(0);
file >> value;
std::cout << "Modified first value: " << value << std::endl;
file.close();
}
int main() {
// Crear un archivo de ejemplo con números
createSampleFile();
// Demostrar las operaciones seek
demonstrateSeekOperations();
return 0;
}
Compile el programa:
g++ file_pointer.cpp -o file_pointer
Ejecute el ejecutable:
./file_pointer
Salida de ejemplo:
Reading operations:
Value at 5th byte: 4
First value: 1
Writing operations:
Modified first value: 100
Puntos clave sobre los punteros de archivo:
seekg(): Mueve el puntero de lectura (get pointer)seekp(): Mueve el puntero de escritura (put pointer)- El primer argumento es la posición en bytes
- Útil para acceso aleatorio en archivos
- Puede navegar a ubicaciones específicas
Puede pensar en los punteros de archivo como un cursor en un editor de texto. seekg() y seekp() le ayudan a mover este cursor con precisión a donde lo desea.
Cerrar Archivos y Liberar Recursos
En este paso, aprenderá sobre la importancia de cerrar archivos correctamente y gestionar recursos en C++ para prevenir fugas de memoria (memory leaks) y asegurar un manejo eficiente de archivos. Explorará diferentes métodos para cerrar archivos y el uso de los principios RAII (Resource Acquisition Is Initialization - Adquisición de Recurso es Inicialización).
Cree un nuevo archivo C++ llamado file_resources.cpp:
touch ~/project/file_resources.cpp
Agregue el siguiente código al archivo file_resources.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <memory>
// Cierre manual de archivos
void manualFileHandling() {
std::ofstream outputFile("manual_file.txt");
if (outputFile.is_open()) {
outputFile << "Manually managed file resource" << std::endl;
// Cierre explícito del archivo
outputFile.close();
std::cout << "File closed manually." << std::endl;
}
}
// Manejo de archivos basado en RAII usando unique_ptr
void raii_fileHandling() {
try {
// Usando unique_ptr para gestionar el recurso del archivo
std::unique_ptr<std::ofstream> file(new std::ofstream("raii_file.txt"));
if (file && file->is_open()) {
*file << "RAII-managed file resource" << std::endl;
std::cout << "RAII file handling successful." << std::endl;
}
// El archivo se cierra automáticamente cuando unique_ptr sale del ámbito (scope)
}
catch (const std::exception& e) {
std::cerr << "Error in RAII file handling: " << e.what() << std::endl;
}
}
// Manejo de archivos basado en el ámbito (scope-based)
void scopeBasedFileHandling() {
{
// El archivo se cerrará automáticamente cuando salga del ámbito
std::ofstream scopedFile("scoped_file.txt");
if (scopedFile.is_open()) {
scopedFile << "Scope-based file resource management" << std::endl;
std::cout << "Scoped file handling successful." << std::endl;
}
} // El archivo se cierra automáticamente aquí
}
int main() {
// Demostrar diferentes técnicas de gestión de recursos de archivos
manualFileHandling();
raii_fileHandling();
scopeBasedFileHandling();
return 0;
}
Compile el programa:
g++ file_resources.cpp -o file_resources
Ejecute el ejecutable:
./file_resources
Salida de ejemplo:
File closed manually.
RAII file handling successful.
Scoped file handling successful.
Puntos clave sobre el cierre de archivos y la gestión de recursos:
- Siempre cierre los archivos después de usarlos
- Use el método
close()para el cierre manual - Aproveche los principios RAII
- Use la gestión de recursos basada en el ámbito (scope-based)
- Prevenga fugas de recursos (resource leaks)
- Maneje excepciones durante las operaciones de archivo
Puede pensar en los recursos de archivos como pedir prestado un libro de una biblioteca. Siempre devuelva el libro (cierre el archivo) cuando haya terminado para mantener la biblioteca (recursos del sistema) organizada.
Resumen
En este laboratorio, aprendió a abrir archivos en C++ utilizando las clases ofstream e ifstream de la biblioteca estándar. Exploró el proceso de verificar el estado de apertura del archivo, escribir datos de texto en archivos y leer datos de archivos de texto. Además, adquirió una comprensión sobre el manejo de errores de lectura/escritura de archivos, el trabajo con archivos binarios usando fstream, la posición del puntero del archivo con seekg/seekp, y el cierre adecuado de archivos y liberación de recursos. Estas operaciones fundamentales de archivo son esenciales para gestionar el almacenamiento y la recuperación de datos en aplicaciones C++.



