3

Debo crear un sistema de almacenamiento de fármacos usando un depósito. Como cada fármaco tiene mucha información (nombre, codigo, stock, precio, concentración), debo usar un struct de C para crear un fármaco. Para almacenar varios fármacos cree un arreglo de punteros al struct de los fármacos. Además de esto, debo pasar la información por la entrada estándar o el stdin. Con un ciclo while estoy pasando la información. Sin embargo, funciona la primera vez y luego no me deja almacenar los campos de los siguientes fármacos. Por ejemplo se ejecuta el siguiente comportamiento:

Ingrese la informacion de un farmaco:
Ingrese el nombre:
Paracetamol
Ingrese el codigo:
1000
Ingrese el stock:
10
Ingrese el valor:
1999.0
Ingrese la concentracion:
10.3
Ingrese la informacion de un farmaco:
Ingrese el nombre:
Ingrese el codigo:
a
Ingrese el stock:
Ingrese el valor:
Ingrese la concentracion:
Ingrese la informacion de un farmaco:
Ingrese el nombre:
Ingrese el codigo:
a
Ingrese el stock:
Ingrese el valor:
Ingrese la concentracion:
Ingrese la informacion de un farmaco:
Ingrese el nombre:
Ingrese el codigo:

Como que no se deja agregar los campos para los siguientes fármacos. Este es el código:

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


typedef struct farmaco {
    char nombre[100];
    int codigo;
    int stock;
    double valor;
    double concentracion;
} Farmaco;

Farmaco* deposito[100];

int main() {
    int i = 0;
    while (i < 5) {
        deposito[i] = (Farmaco*)malloc(sizeof(Farmaco));
        printf("Ingrese la informacion de un farmaco: \n");
        printf("Ingrese el nombre: \n");
        fgets(deposito[i]->nombre, sizeof(deposito[i]->nombre), stdin);
        printf("Ingrese el codigo: \n");
        scanf("%d", &deposito[i]->codigo);
        printf("Ingrese el stock: \n");
        scanf("%d", &deposito[i]->stock);
        printf("Ingrese el valor: \n");
        scanf("%lf", &deposito[i]->valor);
        printf("Ingrese la concentracion: \n");
        scanf("%lf", &deposito[i]->concentracion);
        i++;
    }
    return 0;
}

¿Cuál es el problema?, espero se entienda el problema. Gracias!

mihael
  • 123
  • 1
  • 7
  • Cuando lees enteros o decimales con *scanf*, deja el búfer `stdin` sucio, entonces al ejecutar `fgets` no se detendrá y se salta la opción. Necesitas limpiar el búfer `stdin` después del último *scanf* (en este caso cuando pides la concentración). Y por cierto, si escribes un `a`, obviamente se saltará las opciones, porque no estás respetando el formato, solo puedes ingresar enteros o decimales, ahí en ese caso toca validar los datos. – MrDave1999 Aug 02 '20 at 18:08
  • Y como limpias el stdin? – mihael Aug 02 '20 at 18:21
  • Mira este [hilo](https://es.stackoverflow.com/questions/233445/diferencias-entre-limpiar-el-b%c3%bafer-en-c). – MrDave1999 Aug 02 '20 at 18:26

1 Answers1

0

Como dijo MrDave:

Cuando lees enteros o decimales con scanf, deja el búfer stdin sucio, entonces al ejecutar fgets no se detendrá y se salta la opción.

Lo que puedes hacer es leer los datos como un string. Y del string leer el numero con sscanf. Esta es la funcion que yo he estado usando:

int getInt(char mensaje[]) {
  int numero;
  char strNumero[15];
  printf("%s", mensaje);
  fgets(strNumero, 15, stdin);
  // sscanf regresa la cantidad de argumentos que leyó
  if (sscanf(strNumero, "%i", &numero) != 1) {
    printf("Ingrese un numero entero porfavor\n");
    return getInt(mensaje);
  } else {
    return numero;
  }
}

Luego puedes adaptarla para cualquier tipo de dato que necesites

Pablochaches
  • 2,505
  • 1
  • 5
  • 21