Ejercicio 06 — Guarda un array de 5 structs Producto {nombre, precio} en…

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

Enunciado

Guarda un array de 5 structs Producto {nombre, precio} en productos.txt con fprintf, luego leelos con fscanf y muestralos.

Diagrama de flujo

Diagrama de flujo del ejercicio 06

Cómo se resuelve

Aquí unes lo del módulo de structs con los archivos: persistir en disco un array de structs y luego reconstruirlo leyéndolo. La clave es elegir un formato de texto que puedas volver a leer sin ambigüedad.

  1. Se define typedef struct { char nombre[32]; float precio; } Producto; y se inicializa un catalogo de 5 productos de prueba.
  2. Escritura: se abre productos.txt en "w", se comprueba NULL, y en un bucle se escribe cada producto con fprintf(fw, "%s %.2f\n", ...). Cada línea queda como Manzana 1.20: nombre, un espacio, precio y salto. Luego fclose(fw) vuelca a disco.
  3. Lectura: se reabre en "r" y con while (fscanf(fr, "%31s %f", p.nombre, &p.precio) == 2) se leen los dos campos de golpe. Comparar == 2 significa “he leído correctamente los dos valores de la línea (cadena y float)”; si solo lograra uno, el bucle pararía. Fíjate en que p.nombre es un array y no lleva &, mientras que &p.precio sí, porque es un escalar.
  4. El detalle que hace que todo encaje: el nombre no puede tener espacios. Como %s corta en el primer espacio, si un producto se llamara “Zumo de Naranja”, al releer solo recuperarías “Zumo” y el fscanf se desincronizaría. Por eso se guardan nombres de una sola palabra.

Trampa típica: elegir un formato que no puedes volver a parsear (nombres con espacios rompiendo el %s), olvidar el \n al escribir (todo quedaría en una línea), o el clásico fopen sin comprobar y sin fclose.

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 06 — PRACTICA (rellena los TODO)
  Enunciado: Guarda un array de 5 structs Producto {nombre, precio} en productos.txt
             con fprintf, luego leelos con fscanf y muestralos.
  Dificultad: rojo
  Compilar: gcc -std=c11 -Wall ej06_practica.c -o ej06 && ./ej06
 
  Pista clave: el nombre NO debe tener espacios para poder leerlo de vuelta con %s.
               El formato de cada linea es: "NombreProducto 1.20\n"
*/
 
#include <stdio.h>
 
#define N_PRODUCTOS 5
#define ARCHIVO     "productos.txt"
 
// TODO 1: Define el struct Producto con campos:
//         char nombre[32]  y  float precio
// typedef struct { ... } Producto;
 
int main(void) {
    // TODO 2: Declara e inicializa un array 'catalogo' de 5 Producto con datos de prueba
    //         (nombres sin espacios, precios a tu eleccion)
 
    // TODO 3: Abre ARCHIVO en modo "w"; comprueba NULL
 
    // TODO 4: Bucle for: escribe cada producto con fprintf
    //         Formato sugerido: "%s %.2f\n"  (nombre y precio)
 
    // TODO 5: Cierra el archivo de escritura y confirma con un printf
 
    // TODO 6: Abre ARCHIVO en modo "r"; comprueba NULL
 
    // TODO 7: Bucle con fscanf(fr, "%31s %f", p.nombre, &p.precio) == 2
    //         Imprime cada producto numerado
 
    // TODO 8: 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 06 — MODELO (resuelto)
  Enunciado: Guarda un array de 5 structs Producto {nombre, precio} en productos.txt
             con fprintf, luego leelos con fscanf y muestralos.
  Dificultad: rojo
  Compilar: gcc -std=c11 -Wall ej06_modelo.c -o ej06 && ./ej06
*/
 
#include <stdio.h>
 
#define N_PRODUCTOS 5
#define ARCHIVO     "productos.txt"
 
typedef struct {
    char  nombre[32];
    float precio;
} Producto;
 
int main(void) {
    // Datos de prueba (sin espacios en el nombre para facilitar fscanf)
    Producto catalogo[N_PRODUCTOS] = {
        {"Manzana",  1.20f},
        {"Leche",    0.85f},
        {"Pan",      1.10f},
        {"Huevos",   2.50f},
        {"Naranja",  0.95f}
    };
 
    // --- ESCRITURA ---
    FILE *fw = fopen(ARCHIVO, "w");
    if (fw == NULL) {
        printf("Error: no se pudo crear %s\n", ARCHIVO);
        return 1;
    }
 
    for (int i = 0; i < N_PRODUCTOS; i++) {
        // Formato: "nombre precio\n"  — nombre SIN espacios para poder releerlo con %s
        fprintf(fw, "%s %.2f\n", catalogo[i].nombre, catalogo[i].precio);
    }
    fclose(fw);
    printf("Productos guardados en '%s'.\n\n", ARCHIVO);
 
    // --- LECTURA ---
    FILE *fr = fopen(ARCHIVO, "r");
    if (fr == NULL) {
        printf("Error: no se pudo abrir %s para lectura\n", ARCHIVO);
        return 1;
    }
 
    Producto p;
    int idx = 1;
    printf("%-5s %-20s %s\n", "Num", "Producto", "Precio");
    printf("--------------------------------\n");
 
    // fscanf lee: cadena (%31s) y float (%f)
    while (fscanf(fr, "%31s %f", p.nombre, &p.precio) == 2) {
        printf("%-5d %-20s %.2f EUR\n", idx++, p.nombre, p.precio);
    }
    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