Gestión de Inventario en C: Código Completo y Optimizado

Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones

Escrito el en español con un tamaño de 8,46 KB

Este código en C implementa un sistema básico de gestión de inventario para una pequeña tienda. Permite agregar productos, buscar por nombre, modificar el stock y el precio, y mostrar un listado de los productos existentes. El código está optimizado y comentado para facilitar su comprensión.

Estructuras de Datos

Se utiliza una estructura producto para representar cada artículo del inventario:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 2  // Define el número máximo de productos

struct producto {
    char nombre[50];
    float precio;
    int cantidad;
};

  • nombre: Almacena el nombre del producto (hasta 49 caracteres).
  • precio: Almacena el precio del producto.
  • cantidad: Almacena la cantidad disponible (stock) del producto.

Se define una constante MAX que limita el número máximo de productos que se pueden almacenar en el inventario. En este ejemplo, el límite es 2, pero se puede modificar fácilmente cambiando el valor de MAX.

Funciones

limpiarProductos

Inicializa el arreglo de productos, estableciendo los nombres como "X" y el precio y la cantidad a 0. Esto se hace para evitar valores basura en la memoria.


void limpiarProductos(struct producto bodega[MAX]) {
    int x;
    for (x = 0; x < MAX; x++) {
        strcpy(bodega[x].nombre, "X");
        bodega[x].precio = 0;
        bodega[x].cantidad = 0;
    }
}

mostrarProductos

Muestra un listado de todos los productos en el inventario, incluyendo su nombre, precio y cantidad disponible.


void mostrarProductos(struct producto bodega[MAX]) {
    int x;
    printf("\nLISTADO DE PRODUCTOS\n");
    for (x = 0; x < MAX; x++) {
        printf("Nombre: %s\n", bodega[x].nombre);
        printf("Precio: %.2f\n", bodega[x].precio); // Formato para mostrar dos decimales
        printf("Stock: %d\n", bodega[x].cantidad);
    }
    printf("\nFIN LISTADO\n");
}

agregarProducto

Solicita al usuario los datos de un nuevo producto (nombre, precio y cantidad) y lo agrega al inventario en la posición indicada por el parámetro indice.


void agregarProducto(struct producto bodega[MAX], int indice) {
    struct producto prod;
    printf("Introduzca un nombre: ");
    fflush(stdin); // Limpia el buffer del teclado
    fgets(prod.nombre, sizeof(prod.nombre), stdin); // Usa fgets en lugar de gets
    prod.nombre[strcspn(prod.nombre, "\n")] = 0; // Elimina el salto de línea final de fgets

    printf("Introduzca un precio: ");
    scanf("%f", &prod.precio);

    printf("Introduzca un stock: ");
    scanf("%d", &prod.cantidad);

    strcpy(bodega[indice].nombre, prod.nombre);
    bodega[indice].precio = prod.precio;
    bodega[indice].cantidad = prod.cantidad;
}

Correcciones y mejoras:

  • Se reemplazó gets por fgets para evitar desbordamientos de búfer. fgets es más segura porque limita la cantidad de caracteres que se leen.
  • Se agregó prod.nombre[strcspn(prod.nombre, "\n")] = 0; para eliminar el salto de línea que fgets agrega al final de la cadena.
  • Se añadió fflush(stdin) antes de fgets. Aunque el comportamiento de fflush(stdin) no está definido en el estándar de C, en algunas implementaciones (como Windows) limpia el búfer de entrada, lo que soluciona problemas con la lectura de datos.

main

La función principal del programa. Presenta un menú al usuario con las siguientes opciones:

  1. Alta de producto
  2. Buscar por nombre
  3. Modificar stock y precio
  4. Salir

int main() {
    struct producto prod, productos[MAX];
    int x, opcion;
    int pos = -1; // -1 significa que aún no hay productos ingresados.

    limpiarProductos(productos);
    // mostrarProductos(productos); // Se comenta para no mostrar el listado inicial vacío

    do {
        printf("1- Alta de producto\n");
        printf("2- Buscar por nombre\n");
        printf("3- Modificar stock y precio\n");
        printf("0- Salir\n");
        printf("Introduzca una opcion: ");
        scanf("%d", &opcion);

        switch (opcion) {
            case 1:
                if (pos < MAX - 1) {
                    pos++;
                    agregarProducto(productos, pos);
                    printf("\nProducto creado. \n\n");
                } else {
                    printf("Ya no se pueden ingresar mas productos\n");
                }
                break;

            case 2:
                printf("Introduzca un nombre: ");
                fflush(stdin);
                fgets(prod.nombre, sizeof(prod.nombre), stdin); // Usar fgets
                prod.nombre[strcspn(prod.nombre, "\n")] = 0; // Eliminar \n
                for (x = 0; x < pos + 1; x++) {
                    if (strcmp(productos[x].nombre, prod.nombre) == 0) {
                        printf("\nNombre: %s\n", productos[x].nombre);
                        printf("Precio: %.2f\n", productos[x].precio);
                        printf("Cantidad en Stock: %d\n", productos[x].cantidad);
                    }
                }
                printf("\n\n");
                break;

            case 3:
                printf("Introduzca un nombre: ");
                fflush(stdin);
                fgets(prod.nombre, sizeof(prod.nombre), stdin);
                prod.nombre[strcspn(prod.nombre, "\n")] = 0;

                for (x = 0; x < MAX; x++) {
                    if (strcmp(productos[x].nombre, prod.nombre) == 0) {
                        printf("Introduzca un precio: ");
                        scanf("%f", &productos[x].precio);
                        printf("Introduzca un stock: ");
                        scanf("%d", &productos[x].cantidad);
                        printf("\nProducto modificado.\n");
                    }
                }
                printf("\n\n");
                break;

            case 0:
                printf("\nTerminando programa...\n");
                break;

            default:
                printf("\nOpcion incorrecta\n");
                break;
        }
    } while (opcion != 0);

    // system("PAUSE"); // Mejor usar getchar() para portabilidad
    getchar(); // Espera a que el usuario presione Enter antes de cerrar
    return 0;
}

Mejoras y correcciones:

  • Se ha comentado la llamada a mostrarProductos() al inicio, ya que muestra el inventario vacío.
  • Se utiliza fgets y se elimina el salto de línea (\n) en las opciones 2 y 3, de forma consistente con la función agregarProducto.
  • Se reemplazó system("PAUSE") por getchar(). system("PAUSE") es específico de Windows y no es portable. getchar() espera a que el usuario presione una tecla, logrando el mismo efecto de forma más portable.
  • Se agregó formato %.2f para mostrar el precio con dos decimales en la función mostrarProductos y en la opción 2 del menú.

Consideraciones Adicionales

  • Manejo de errores: El código no incluye un manejo de errores robusto. Por ejemplo, no verifica si el usuario introduce un valor no numérico al ingresar el precio o la cantidad. Se podría agregar validación de entrada para mejorar la robustez del programa.
  • Persistencia de datos: Los datos del inventario se pierden al cerrar el programa. Para que los datos sean persistentes, se podría guardar la información en un archivo de texto o en una base de datos.
  • Búsqueda más eficiente: La búsqueda por nombre se realiza de forma lineal, recorriendo todo el arreglo de productos. Si el inventario fuera muy grande, esto podría ser ineficiente. Se podrían utilizar estructuras de datos más eficientes, como tablas hash o árboles binarios de búsqueda, para mejorar el rendimiento de la búsqueda.
  • Interfaz de usuario: La interfaz de usuario es muy básica. Se podría mejorar utilizando una biblioteca de interfaz gráfica de usuario (GUI) o una biblioteca de manipulación de la consola como ncurses.

Entradas relacionadas: