Realizar operaciones de archivos en C++

C++C++Beginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo 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 de archivos de texto, la comprobación del estado de apertura de archivos, el manejo de errores de lectura/escritura de archivos, el trabajo con archivos binarios, la posición del puntero de archivo y el cierre de archivos para liberar recursos. Obtendrás 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 final de este laboratorio, tendrás una comprensión sólida del manejo de archivos en la programación en C++.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL cpp(("C++")) -.-> cpp/IOandFileHandlingGroup(["I/O and File Handling"]) cpp(("C++")) -.-> cpp/StandardLibraryGroup(["Standard Library"]) cpp(("C++")) -.-> cpp/BasicsGroup(["Basics"]) cpp(("C++")) -.-> cpp/ControlFlowGroup(["Control Flow"]) cpp(("C++")) -.-> cpp/AdvancedConceptsGroup(["Advanced Concepts"]) cpp/BasicsGroup -.-> cpp/strings("Strings") cpp/ControlFlowGroup -.-> cpp/if_else("If...Else") cpp/AdvancedConceptsGroup -.-> cpp/pointers("Pointers") cpp/AdvancedConceptsGroup -.-> cpp/structures("Structures") cpp/AdvancedConceptsGroup -.-> cpp/exceptions("Exceptions") cpp/IOandFileHandlingGroup -.-> cpp/output("Output") cpp/IOandFileHandlingGroup -.-> cpp/files("Files") cpp/StandardLibraryGroup -.-> cpp/string_manipulation("String Manipulation") subgraph Lab Skills cpp/strings -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/if_else -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/pointers -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/structures -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/exceptions -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/output -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/files -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} cpp/string_manipulation -.-> lab-446086{{"Realizar operaciones de archivos en C++"}} end

Abrir archivos usando ofstream e ifstream

En este paso, aprenderás cómo abrir archivos en C++ utilizando dos clases fundamentales de flujo de archivos: ofstream para escribir archivos e ifstream para leer archivos. Estas clases forman parte de la biblioteca estándar de C++ y proporcionan capacidades esenciales de manejo de archivos.

Primero, navega hasta el directorio del proyecto en la terminal del WebIDE:

cd ~/project

Crea un nuevo archivo C++ llamado file_operations.cpp:

touch file_operations.cpp

Agrega el siguiente código al archivo file_operations.cpp:

#include <iostream>
#include <fstream>  // Include file stream header

int main() {
    // Opening a file for writing using ofstream
    std::ofstream outputFile("example.txt");

    // Check if the file is successfully opened
    if (outputFile.is_open()) {
        std::cout << "File opened for writing successfully!" << std::endl;
        outputFile.close();  // Close the file
    } else {
        std::cout << "Unable to open file for writing." << std::endl;
    }

    // Opening a file for reading using ifstream
    std::ifstream inputFile("example.txt");

    // Check if the file is successfully opened
    if (inputFile.is_open()) {
        std::cout << "File opened for reading successfully!" << std::endl;
        inputFile.close();  // Close the file
    } else {
        std::cout << "Unable to open file for reading." << std::endl;
    }

    return 0;
}

Analicemos los conceptos clave:

  1. #include <fstream>: Incluye la biblioteca de flujo de archivos
  2. std::ofstream: Flujo de archivo de salida para escribir archivos
  3. std::ifstream: Flujo de archivo de entrada para leer archivos
  4. is_open(): Comprueba si el archivo se abrió correctamente
  5. close(): Cierra el archivo después de las operaciones

Compila el programa:

g++ file_operations.cpp -o file_operations

Ejecuta el archivo ejecutable:

./file_operations

Ejemplo de salida:

File opened for writing successfully!
File opened for reading successfully!

Algunos puntos importantes sobre los flujos de archivos:

  • Siempre comprueba si un archivo se abrió correctamente antes de realizar operaciones
  • Recuerda cerrar los archivos después de usarlos
  • ofstream se utiliza para escribir en archivos
  • ifstream se utiliza para leer de archivos
  • Ambas clases forman parte del encabezado <fstream>

Puedes pensar en los flujos de archivos como abrir y cerrar puertas a los archivos. ofstream te permite escribir en una habitación, mientras que ifstream te permite leer lo que hay dentro.

Escribir datos de texto en archivos

En este paso, aprenderás cómo escribir datos de texto en archivos utilizando la clase ofstream en C++. Basándote en el paso anterior, explorarás diferentes formas de escribir cadenas, números y múltiples líneas en archivos.

Crea un nuevo archivo C++ llamado write_files.cpp:

touch ~/project/write_files.cpp

Agrega el siguiente código al archivo write_files.cpp:

#include <iostream>
#include <fstream>
#include <string>

int main() {
    // Open a file for writing
    std::ofstream outputFile("student_data.txt");

    // Check if the file is successfully opened
    if (outputFile.is_open()) {
        // Writing a single string
        outputFile << "John Doe" << std::endl;

        // Writing multiple pieces of data
        std::string name = "Alice Smith";
        int age = 22;
        double gpa = 3.75;
        outputFile << name << ", " << age << " years old, GPA: " << gpa << std::endl;

        // Writing multiple lines
        outputFile << "Computer Science Student" << std::endl;
        outputFile << "University of Programming" << std::endl;

        // Close the file
        outputFile.close();
        std::cout << "Data written to file successfully!" << std::endl;
    } else {
        std::cout << "Unable to open file for writing." << std::endl;
    }

    return 0;
}

Compila el programa:

g++ write_files.cpp -o write_files

Ejecuta el archivo ejecutable:

./write_files

Ejemplo de salida:

Data written to file successfully!

Verifica el contenido del archivo:

cat student_data.txt

Ejemplo de contenido 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:

  • Utiliza el operador << para escribir datos en archivos
  • std::endl agrega una nueva línea
  • Puedes escribir cadenas, números y variables
  • Siempre comprueba si el archivo está abierto antes de escribir
  • Cierra el archivo después de las operaciones de escritura

Puedes pensar en escribir en archivos como escribir en un cuaderno. El ofstream es tu pluma y el archivo es la página donde registras información.

Leer datos de archivos de texto

En este paso, aprenderás cómo leer datos de archivos de texto utilizando la clase ifstream en C++. Basándote en los pasos anteriores, explorarás diferentes métodos para leer líneas, palabras y archivos enteros.

Crea un nuevo archivo C++ llamado read_files.cpp:

touch ~/project/read_files.cpp

Agrega el siguiente código al archivo read_files.cpp:

#include <iostream>
#include <fstream>
#include <string>

int main() {
    // Open the file created in the previous step
    std::ifstream inputFile("student_data.txt");

    // Check if the file is successfully opened
    if (inputFile.is_open()) {
        // Read entire line
        std::string line;
        std::cout << "Reading entire lines:" << std::endl;
        while (std::getline(inputFile, line)) {
            std::cout << line << std::endl;
        }

        // Reset file pointer to beginning
        inputFile.clear();
        inputFile.seekg(0, std::ios::beg);

        // Read individual words
        std::cout << "\nReading individual words:" << std::endl;
        std::string word;
        while (inputFile >> word) {
            std::cout << word << " ";
        }
        std::cout << std::endl;

        // Close the file
        inputFile.close();
    } else {
        std::cout << "Unable to open file for reading." << std::endl;
    }

    return 0;
}

Compila el programa:

g++ read_files.cpp -o read_files

Ejecuta el archivo ejecutable:

./read_files

Ejemplo de salida:

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:

  • Utiliza std::getline() para leer líneas enteras
  • Utiliza el operador >> para leer palabras individuales
  • clear() y seekg() restablecen el puntero del archivo
  • Siempre comprueba si el archivo está abierto antes de leer
  • Cierra el archivo después de las operaciones de lectura

Puedes pensar en la lectura de archivos como extraer información de un libro. El ifstream es tu marcador de página, que te ayuda a navegar por el texto.

Comprobar el estado de apertura de archivos

En este paso, aprenderás cómo comprobar el estado de las operaciones de archivos en C++ utilizando varios métodos para verificar si los archivos se abrieron correctamente y están listos para lectura o escritura.

Crea un nuevo archivo C++ llamado file_status.cpp:

touch ~/project/file_status.cpp

Agrega el siguiente código al archivo file_status.cpp:

#include <iostream>
#include <fstream>
#include <string>

int main() {
    // Attempt to open an existing file for reading
    std::ifstream inputFile("student_data.txt");

    // Method 1: Using is_open() to check file status
    if (inputFile.is_open()) {
        std::cout << "File opened successfully for reading." << std::endl;

        // Perform reading operations
        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;
    }

    // Method 2: Using good() to check file state
    std::ofstream outputFile("test_status.txt");

    if (outputFile.good()) {
        std::cout << "File opened successfully for writing." << std::endl;
        outputFile << "Testing file status" << std::endl;

        // Additional status checks
        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;
    }

    // Method 3: Multiple status check methods
    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;
}

Compila el programa:

g++ file_status.cpp -o file_status

Ejecuta el archivo ejecutable:

./file_status

Ejemplo de salida:

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 de archivos:

  • is_open(): Comprueba si el archivo se abrió correctamente
  • good(): Comprueba si no se han producido errores
  • fail(): Comprueba si se ha producido un error
  • Siempre comprueba el estado del archivo antes de realizar operaciones
  • Diferentes métodos proporcionan diversas formas de verificar el estado del archivo

Puedes pensar en las comprobaciones del estado de archivos como una inspección de seguridad antes de un viaje. Estos métodos ayudan a garantizar que tus operaciones de archivos sean seguras y exitosas.

Manejar errores de lectura/escritura de archivos

En este paso, aprenderás cómo manejar los 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.

Crea un nuevo archivo C++ llamado file_error_handling.cpp:

touch ~/project/file_error_handling.cpp

Agrega 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);

    // Check if file is open
    if (!outputFile) {
        // Throw an exception if file cannot be opened
        throw std::runtime_error("Unable to open file for writing: " + filename);
    }

    try {
        // Attempt to write data
        outputFile << "Hello, Error Handling!" << std::endl;
        outputFile << "This is a sample text." << std::endl;

        // Simulate a write error (intentionally not recommended)
        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;

    // Check if file is open
    if (!inputFile) {
        // Throw an exception if file cannot be opened
        throw std::runtime_error("Unable to open file for reading: " + filename);
    }

    try {
        // Read and print file contents
        std::cout << "File contents:" << std::endl;
        while (std::getline(inputFile, line)) {
            std::cout << line << std::endl;
        }

        // Check for read errors
        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 {
        // Write to a file
        writeToFile("error_handling_example.txt");

        // Read from the file
        readFromFile("error_handling_example.txt");

        // Attempt to read from a non-existent file
        readFromFile("non_existent_file.txt");
    }
    catch (const std::exception& e) {
        std::cerr << "Main error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

Compila el programa:

g++ file_error_handling.cpp -o file_error_handling

Ejecuta el archivo ejecutable:

./file_error_handling

Ejemplo de salida:

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:

  • Utiliza bloques try-catch para manejar posibles excepciones
  • Comprueba el estado del flujo de archivos antes y después de las operaciones
  • Utiliza std::runtime_error para lanzar mensajes de error significativos
  • Maneja diferentes tipos de errores relacionados con archivos
  • Proporciona mensajes de error informativos

Puedes pensar en el manejo de errores como una red de seguridad. Captura los posibles problemas y evita que tu programa se bloquee inesperadamente.

Trabajar con archivos binarios utilizando fstream

En este paso, aprenderás cómo trabajar con archivos binarios utilizando la clase fstream en C++. Los archivos binarios almacenan datos en su formato binario sin procesar, lo cual es diferente a los archivos de texto y es útil para almacenar datos estructurados de manera eficiente.

Crea un nuevo archivo C++ llamado binary_files.cpp:

touch ~/project/binary_files.cpp

Agrega el siguiente código al archivo binary_files.cpp:

#include <iostream>
#include <fstream>
#include <string>

// Simple struct to demonstrate binary file writing
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;
    }

    // Create some student records
    Student students[3] = {
        {1, "John Doe", 3.5},
        {2, "Alice Smith", 3.8},
        {3, "Bob Johnson", 3.2}
    };

    // Write entire struct to binary file
    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];

    // Read entire struct from binary file
    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() {
    // Write binary file
    writeBinaryFile();

    // Read binary file
    readBinaryFile();

    return 0;
}

Compila el programa:

g++ binary_files.cpp -o binary_files

Ejecuta el archivo ejecutable:

./binary_files

Ejemplo de salida:

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:

  • Utiliza la bandera std::ios::binary para el modo binario
  • Métodos write() y read() para datos binarios
  • reinterpret_cast se utiliza para convertir entre tipos
  • Útil para almacenar datos estructurados de manera eficiente
  • Preserva la representación binaria exacta de los datos

Puedes pensar en los archivos binarios como un plano técnico preciso. Almacenan los datos exactamente como existen en la memoria, sin ninguna conversión de texto.

Posicionar el puntero de archivo con seekg/seekp

En este paso, aprenderás cómo manipular los punteros de archivo utilizando seekg() para lectura y seekp() para escritura en C++. Estos métodos te permiten navegar y modificar posiciones específicas dentro de un archivo.

Crea un nuevo archivo C++ llamado file_pointer.cpp:

touch ~/project/file_pointer.cpp

Agrega 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() {
    // Open file in read and write mode
    std::fstream file("numbers.txt", std::ios::in | std::ios::out);

    if (!file) {
        std::cerr << "Error opening file!" << std::endl;
        return;
    }

    // Reading from different positions
    std::cout << "Reading operations:" << std::endl;

    // Move to the 5th byte (character position)
    file.seekg(5);
    int value;
    file >> value;
    std::cout << "Value at 5th byte: " << value << std::endl;

    // Move to the beginning of the file
    file.seekg(0);
    file >> value;
    std::cout << "First value: " << value << std::endl;

    // Writing at specific positions
    std::cout << "\nWriting operations:" << std::endl;

    // Move to a specific position and write
    file.seekp(0);
    file << "100 ";

    // Reset file pointer and read to verify
    file.seekg(0);
    file >> value;
    std::cout << "Modified first value: " << value << std::endl;

    file.close();
}

int main() {
    // Create a sample file with numbers
    createSampleFile();

    // Demonstrate seek operations
    demonstrateSeekOperations();

    return 0;
}

Compila el programa:

g++ file_pointer.cpp -o file_pointer

Ejecuta el archivo ejecutable:

./file_pointer

Ejemplo de salida:

Reading operations:
Value at 5th byte: 4
First value: 1

Writing operations:
Modified first value: 10

Puntos clave sobre los punteros de archivo:

  • seekg(): Mueve el puntero de lectura (puntero get)
  • seekp(): Mueve el puntero de escritura (puntero put)
  • El primer argumento es la posición en bytes
  • Útil para el acceso aleatorio en archivos
  • Puedes navegar a ubicaciones específicas

Puedes pensar en los punteros de archivo como un cursor en un editor de texto. seekg() y seekp() te ayudan a mover este cursor precisamente a donde quieres.

Cerrar archivos y liberar recursos

En este paso, aprenderás sobre la importancia de cerrar adecuadamente los archivos y gestionar los recursos en C++ para prevenir fugas de memoria y garantizar un manejo eficiente de archivos. Explorarás diferentes métodos para cerrar archivos y utilizar los principios de RAII (Resource Acquisition Is Initialization, Adquisición de Recursos es Inicialización).

Crea un nuevo archivo C++ llamado file_resources.cpp:

touch ~/project/file_resources.cpp

Agrega el siguiente código al archivo file_resources.cpp:

#include <iostream>
#include <fstream>
#include <string>
#include <memory>

// Manual file closing
void manualFileHandling() {
    std::ofstream outputFile("manual_file.txt");

    if (outputFile.is_open()) {
        outputFile << "Manually managed file resource" << std::endl;

        // Explicitly close the file
        outputFile.close();

        std::cout << "File closed manually." << std::endl;
    }
}

// RAII-based file handling using unique_ptr
void raii_fileHandling() {
    try {
        // Using unique_ptr to manage file resource
        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;
        }
        // File automatically closed when unique_ptr goes out of scope
    }
    catch (const std::exception& e) {
        std::cerr << "Error in RAII file handling: " << e.what() << std::endl;
    }
}

// Scope-based file handling
void scopeBasedFileHandling() {
    {
        // File will be automatically closed when it goes out of scope
        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;
        }
    } // File automatically closed here
}

int main() {
    // Demonstrate different file resource management techniques
    manualFileHandling();
    raii_fileHandling();
    scopeBasedFileHandling();

    return 0;
}

Compila el programa:

g++ file_resources.cpp -o file_resources

Ejecuta el archivo ejecutable:

./file_resources

Ejemplo de salida:

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 cierra los archivos después de usarlos
  • Utiliza el método close() para el cierre manual
  • Aprovecha los principios de RAII
  • Utiliza la gestión de recursos basada en el ámbito (scope)
  • Previene fugas de recursos
  • Maneja las excepciones durante las operaciones de archivos

Puedes pensar en los recursos de archivo como si estuvieras pidiendo prestado un libro de una biblioteca. Siempre devuelve el libro (cierra el archivo) cuando hayas terminado para mantener la biblioteca (los recursos del sistema) organizada.

Resumen

En este laboratorio, aprendiste cómo abrir archivos en C++ utilizando las clases ofstream e ifstream de la biblioteca estándar. Exploraste el proceso de comprobar el estado de apertura de un archivo, escribir datos de texto en archivos y leer datos de archivos de texto. Además, adquiriste una comprensión del manejo de errores de lectura/escritura de archivos, el trabajo con archivos binarios utilizando fstream, la posición del puntero de archivo con seekg/seekp y el cierre adecuado de archivos y liberación de recursos. Estas operaciones fundamentales de archivos son esenciales para gestionar el almacenamiento y recuperación de datos en aplicaciones de C++.