Ejercicio 07 — Abre un archivo en modo append y permite anadir lineas hasta escribir…

Dificultad: rojo · Módulo 09 (Lectura y escritura de archivos)

Enunciado

Abre un archivo en modo append y permite anadir lineas hasta escribir “FIN”. Al terminar, muestra todo el archivo.

Diagrama de flujo

Diagrama de flujo del ejercicio 07

Cómo se resuelve

Este ejercicio estrena el tercer modo de apertura, "a" (append), y lo combina con una lectura final. Es el más completo del módulo.

  1. FILE *fa = fopen(ARCHIVO, "a") abre diario.txt en modo append: a diferencia de "w", no borra lo que ya había; siempre escribe al final. Así, cada vez que ejecutas el programa, las líneas nuevas se suman a las de veces anteriores. Se comprueba NULL como siempre.
  2. Antes de leer del teclado se vacía stdin con un bucle getchar, para que no queden residuos de una entrada previa.
  3. El bucle while (1) va pidiendo líneas con fgets. Por cada una: se le quita el \n con buf[strcspn(buf, "\n")] = '\0', se compara con strcmp(buf, "FIN") == 0 para decidir si parar, y si no es el fin se guarda con fprintf(fa, "%s\n", buf) reponiendo el salto de línea. strcmp devuelve 0 cuando las dos cadenas son iguales (en C no puedes comparar cadenas con ==).
  4. fclose(fa) cierra la fase de escritura. Este cierre es imprescindible antes de la siguiente fase: si no vaciaras el buffer a disco, al reabrir para leer podrías no ver las líneas que acabas de añadir.
  5. Se reabre en "r" y se recorre todo el archivo con fgets, imprimiendo cada línea numerada. Así ves el histórico completo, no solo lo de esta sesión.

Trampa típica: usar "w" en vez de "a" (borrarías el diario entero en cada ejecución), intentar comparar cadenas con == en lugar de strcmp, y no cerrar el archivo de append antes de releerlo.

Para practicar — cópialo en Dev-C++

Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.

/*
  Curso de C — Modulo 09: Lectura y escritura de archivos
  Ejercicio 07 — PRACTICA (rellena los TODO)
  Enunciado: Abre un archivo en modo append y permite anadir lineas hasta escribir "FIN".
             Al terminar, muestra todo el archivo.
  Dificultad: rojo
  Compilar: gcc -std=c11 -Wall ej07_practica.c -o ej07 && ./ej07
 
  Pistas:
  - Modo "a" (append): abre el archivo sin borrar lo que ya habia, escribe al final.
  - strcmp(a, b) == 0 compara cadenas (incluye <string.h>).
  - strcspn(buf, "\n") devuelve el indice del '\n'; ponlo a '\0' para eliminarlo.
*/
 
#include <stdio.h>
#include <string.h>
 
#define ARCHIVO "diario.txt"
#define MAX_LEN 256
 
int main(void) {
    // TODO 1: Abre ARCHIVO en modo "a" (append)
    //         Comprueba NULL
 
    printf("Escribe lineas para anadir a '%s'.\n", ARCHIVO);
    printf("Escribe FIN (en mayusculas) para terminar.\n\n");
 
    char buf[MAX_LEN];
    int anadidas = 0;
 
    // TODO 2: Vacia stdin antes de usar fgets
    //         (bucle getchar hasta '\n' o EOF)
 
    // TODO 3: Bucle infinito (while(1)):
    //         a) Imprime "> " como prompt
    //         b) Lee con fgets; si devuelve NULL, sal del bucle (EOF)
    //         c) Elimina el '\n' del buffer con strcspn
    //         d) Si el buffer es "FIN", sal del bucle (break)
    //         e) Escribe la linea en el archivo con fprintf (repon el '\n')
    //         f) Incrementa 'anadidas'
 
    // TODO 4: Cierra el archivo de append
    //         Imprime cuantas lineas anadiste
 
    // TODO 5: Abre ARCHIVO en modo "r" para mostrar todo su contenido
    //         Comprueba NULL
 
    // TODO 6: Bucle con fgets hasta EOF
    //         Imprime cada linea numerada (quita el '\n' primero)
 
    // TODO 7: Cierra el archivo de lectura
 
    return 0;
}

Solución — cópiala y ejecútala

/*
  Curso de C — Modulo 09: Lectura y escritura de archivos
  Ejercicio 07 — MODELO (resuelto)
  Enunciado: Abre un archivo en modo append y permite anadir lineas hasta escribir "FIN".
             Al terminar, muestra todo el archivo.
  Dificultad: rojo
  Compilar: gcc -std=c11 -Wall ej07_modelo.c -o ej07 && ./ej07
*/
 
#include <stdio.h>
#include <string.h>
 
#define ARCHIVO "diario.txt"
#define MAX_LEN 256
 
int main(void) {
    // --- FASE APPEND: anadir nuevas lineas ---
    FILE *fa = fopen(ARCHIVO, "a");
    if (fa == NULL) {
        printf("Error: no se pudo abrir '%s' en modo append\n", ARCHIVO);
        return 1;
    }
 
    printf("Escribe lineas para anadir a '%s'.\n", ARCHIVO);
    printf("Escribe FIN (en mayusculas) para terminar.\n\n");
 
    char buf[MAX_LEN];
    int anadidas = 0;
 
    // Vaciar stdin antes de fgets
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
 
    while (1) {
        printf("> ");
        if (fgets(buf, sizeof(buf), stdin) == NULL) break; // EOF (Ctrl+D)
 
        // Quitar el '\n' para comparar con "FIN"
        buf[strcspn(buf, "\n")] = '\0';
 
        if (strcmp(buf, "FIN") == 0) break;
 
        // Volver a poner el '\n' para guardar correctamente
        fprintf(fa, "%s\n", buf);
        anadidas++;
    }
    fclose(fa);
    printf("\n%d linea(s) anadida(s).\n\n", anadidas);
 
    // --- FASE LECTURA: mostrar todo el archivo ---
    FILE *fr = fopen(ARCHIVO, "r");
    if (fr == NULL) {
        printf("Error: no se pudo releer '%s'\n", ARCHIVO);
        return 1;
    }
 
    printf("--- Contenido completo de '%s' ---\n", ARCHIVO);
    int num = 1;
    while (fgets(buf, sizeof(buf), fr) != NULL) {
        buf[strcspn(buf, "\n")] = '\0';
        printf("%3d | %s\n", num++, buf);
    }
    fclose(fr);
    return 0;
}

Cómo usarlo

Dev-C++ (Windows): Archivo → Nuevo → Código fuente, pega el código y pulsa F11 (compilar y ejecutar). Si ves los acentos raros en la consola, escribe chcp 65001 y vuelve a ejecutar.

Conexiones