HOWTO · C++

Cómo escribir en un archivo en C++

Este artículo muestra cómo escribir en un archivo en C++. Aprenda sobre los flujos de archivo y los distintos modos de apertura, y vea ejemplos claros para gestionar eficazmente las operaciones con archivos en sus programas de C++. Tanto si necesita añadir datos como sobrescribir el contenido existente, esta guía le resultará útil.

En esta página

Usa std::ofstream con el operador de inserción (<<) para escribir texto normal en un archivo. Ábrelo con std::ios::app para añadir datos al final, o usa std::ios::trunc si quieres reemplazar el contenido existente. Si conoces la cantidad de caracteres o bytes que debes escribir, usa la función miembro write de un flujo; fwrite es la alternativa equivalente al estilo de C.

Comprender los flujos de archivo en C++

Los flujos de archivo conectan un programa de C++ con un archivo con nombre. Incluye <fstream> y crea un std::ofstream para escribir; usa std::fstream cuando necesites que el mismo flujo sirva tanto para leer como para escribir. El operador de inserción resulta práctico para texto con formato, y un carácter de nueva línea en la cadena inicia otra línea en el archivo. Comprueba el estado del flujo después de abrir y escribir: aunque la ruta parezca válida, puede que no sea accesible o que no haya espacio disponible.

Ejecuta este ejemplo:

#include <fstream>
#include <iostream>

int main() {
    std::ofstream file("example.txt");
    if (!file) {
        std::cerr << "Could not open example.txt\n";
        return 1;
    }

    file << "Hello, C++!\n";
    file << "File output is ready.\n";
    file.close();
    if (!file) {
        std::cerr << "Could not finish writing example.txt\n";
        return 1;
    }

    std::cout << "Wrote example.txt\n";
    return 0;
}
Wrote example.txt

El mensaje se imprime en la consola; las dos líneas escritas mediante file se guardan en example.txt. Abre ese archivo con un editor de texto para revisar su contenido. Un std::ofstream de solo salida, abierto con las opciones predeterminadas, crea el archivo si existe el directorio contenedor y normalmente vacía cualquier contenido anterior al abrirlo.

Escribir en archivos con distintos modos

El modo de apertura determina qué ocurre con los datos existentes. std::ios::app sitúa cada escritura al final del archivo, lo que resulta útil para registros o entradas que deban acumularse. Si el archivo no existe, abrirlo para escribir puede crearlo, siempre que la ruta y los permisos lo permitan. El siguiente ejemplo independiente escribe una línea en modo de anexado; no hace falta que example.txt ya exista.

#include <fstream>
#include <iostream>

int main() {
    std::ofstream file("example.txt", std::ios::app);
    if (!file) {
        std::cerr << "Could not open example.txt\n";
        return 1;
    }

    file << "A new log entry\n";
    file.close();
    if (!file) {
        std::cerr << "Could not finish writing example.txt\n";
        return 1;
    }
    return 0;
}

El caso de ejecución proporcionado finalizó correctamente y no produjo salida en la consola. El código escribe A new log entry seguido de un carácter de nueva línea; si el archivo ya contiene datos, la nueva línea se añade a continuación.

Escribir y sobrescribir archivos con ios::trunc

std::ios::trunc descarta el contenido anterior del archivo al abrirlo. Abrir un std::ofstream para escribir sin std::ios::app normalmente también trunca el archivo, así que especifica std::ios::trunc cuando quieras dejar esa decisión explícita. No uses ninguna de estas opciones si necesitas conservar los datos anteriores.

#include <fstream>
#include <iostream>

int main() {
    std::ofstream file("example.txt", std::ios::trunc);
    if (!file) {
        std::cerr << "Could not open example.txt\n";
        return 1;
    }

    file << "Current report\n";
    file.close();
    if (!file) {
        std::cerr << "Could not finish writing example.txt\n";
        return 1;
    }
    return 0;
}

El caso de ejecución proporcionado finalizó correctamente y no produjo salida en la consola. El código escribe únicamente Current report y un carácter de nueva línea en example.txt, reemplazando cualquier contenido anterior.

Escribir en un archivo con fstream::write

Usa la función miembro write del flujo cuando los datos ya estén en un búfer de caracteres y conozcas su longitud. Recibe un puntero a caracteres y la cantidad que se debe escribir; no añade por sí sola un terminador ni un carácter de nueva línea. La cantidad es un tamaño de flujo, por lo que pasar data.size() escribe los caracteres almacenados en la cadena sin incluir un carácter nulo final. Comprueba el estado del flujo después de la llamada para detectar errores de escritura. Consulta la documentación de cppreference sobre basic_ostream::write para conocer su interfaz.

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

int main() {
    const std::string data = "C++ buffer data\n";
    std::fstream file("buffer.txt", std::ios::out | std::ios::trunc);
    if (!file) {
        std::cerr << "Could not open buffer.txt\n";
        return 1;
    }

    file.write(data.data(), static_cast<std::streamsize>(data.size()));
    if (!file) {
        std::cerr << "Could not write buffer.txt\n";
        return 1;
    }
    file.close();
    if (!file) {
        std::cerr << "Could not finish writing buffer.txt\n";
        return 1;
    }
    return 0;
}

El caso de ejecución proporcionado finalizó correctamente y no produjo salida en la consola. Escribe los caracteres de data en buffer.txt; el carácter de nueva línea forma parte de la cadena, pero no se escribe ningún carácter nulo final.

La escritura de caracteres y la escritura de bytes se diferencian en si los datos se formatean o no. El operador de inserción convierte los valores en texto, mientras que write y fwrite copian los bytes del búfer sin formatearlos. Copiar los bytes no garantiza por sí solo que lleguen al archivo sin cambios: un flujo abierto en modo texto todavía puede traducir los caracteres de nueva línea en plataformas que usan un final de línea diferente, como Windows, que convierte \n en \r\n al escribir. Cuando los bytes exactos importan, abra el flujo en modo binario, por ejemplo con std::ios::out | std::ios::binary | std::ios::trunc, o pase "wb" en lugar de "w" a fopen, para que no se produzca ninguna traducción.

Escribir en un archivo con la función de C fwrite

Para la entrada y salida de archivos al estilo de C, fwrite recibe un puntero, el tamaño de cada elemento, la cantidad de elementos y un FILE*. El valor que devuelve es la cantidad de elementos escritos, no la cantidad de bytes, salvo que cada elemento tenga tamaño uno. Comprueba ese valor, cierra el archivo y comprueba también el resultado de fclose, porque los errores de escritura en búfer pueden aparecer al cerrar.

#include <cstdio>
#include <cstring>
#include <iostream>

int main() {
    const char data[] = "C file output\n";
    const std::size_t size = std::strlen(data);
    std::FILE* file = std::fopen("c-output.txt", "w");
    if (file == nullptr) {
        std::cerr << "Could not open c-output.txt\n";
        return 1;
    }

    const std::size_t written = std::fwrite(data, 1, size, file);
    const int close_status = std::fclose(file);
    if (written != size || close_status != 0) {
        std::cerr << "Could not finish writing c-output.txt\n";
        return 1;
    }
    return 0;
}

El caso de ejecución proporcionado finalizó correctamente y no produjo salida en la consola. El código escribe en c-output.txt los caracteres de data, incluido el carácter de nueva línea; el modo "w" crea el archivo o trunca su contenido anterior.

Conclusión

Para texto normal, usa std::ofstream y <<. Elige std::ios::app para conservar el contenido anterior y añadir datos al final, o std::ios::trunc para reemplazarlo. Usa write con un búfer de longitud conocida y recurre a fwrite cuando trabajes con entrada y salida al estilo de C. Comprueba el estado al abrir y escribir, y revisa los errores al cerrar cuando necesites saber si los datos se escribieron por completo.

Preguntas frecuentes

  1. ¿Cómo puedo saber si se abrió un archivo? Comprueba directamente el flujo (if (!file)) o llama a is_open() justo después de abrirlo. Si falla, gestiona el error antes de escribir.

  2. ¿Cómo puedo añadir datos sin reemplazar el contenido existente? Abre un flujo de salida con std::ios::app. Cada escritura se dirige al final del archivo.

  3. ¿C++ crea un archivo que no existe? Los flujos de salida y fopen con el modo "w" pueden crearlo si existe el directorio contenedor y el proceso tiene permiso. Si falta el directorio contenedor o no hay permisos suficientes, la apertura falla.

  4. ¿Cómo escribo varias líneas? Inserta caracteres de nueva línea con << o inclúyelos en el búfer que pasas a write. Ni write ni fwrite añaden finales de línea automáticamente.

  5. ¿Debo cerrar el archivo? El flujo de archivo se cierra cuando se destruye, pero llamar explícitamente a close() puede dejar claro cuándo termina la operación. Comprueba el estado del flujo después de cerrarlo si necesitas confirmar que la escritura terminó. Para un FILE* de C, llama a fclose y comprueba el valor que devuelve.