0

So, I've made this code, and it works wonderfully, but the problem is that I've got some scanf functions only accepting numbers, and some others only accepting characters, but for example, when I input a character on a scanf that requires an int value, the program behaves really unexpectedly, doing stuff such as repeating the same printf all over the command prompt, or repeating it thrice.

Here's the code:

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

int descuento(int num, int descuento);
int rangoValido(int Rangomin, int Rangomax, int i);
int numeroRandom();
int sino(char sino);

 int main(void){
    

    int productoid[1000][1];
    int idprompt;
    int descuento25[14] = {398, 309, 281, 948, 19, 67, 187, 80, 889, 482, 566, 24, 87, 98};
    int descuento15[14] = {992, 788, 987, 90, 155, 596, 27, 587, 98, 273, 344, 69, 89, 234};
    char respuesta;
    int listacompra[100][1];
    int precio;
    int colector = 0;
    int comprobante = 0;
    int total;
    int monto;

    
   //Si la id del producto no esta dentro del rango valido, el bloque se repite 
    do{
    do{
    do{
        
        printf("Escriba la ID del producto: ");
        scanf("%d", &idprompt);
        }
        
        
        
    while(0==rangoValido(1,1000,idprompt));
    
    //Una vez comprobada la validez del numero ingresado, se crea un numero aleatorio que se le 
 asigna para el precio, idprompt es la misma id
        
        comprobante = 0;
        srand(idprompt);
        productoid[idprompt][1]=numeroRandom();
        printf("ID del producto: %d\n", idprompt);
        printf("Precio del producto: %d\n", productoid[idprompt][1]);
        precio = productoid[idprompt][1];
        
        
    //Comprobacion de descuentos
        for(int i=0; i<=14; i++){
            if(descuento25[i]==idprompt){
                productoid[idprompt][1] = descuento(productoid[idprompt][1],25);
                printf("Descuento del producto: 25\n"); 
                }else{
                if(descuento15[i]==idprompt){
                    productoid[idprompt][1] = descuento(productoid[idprompt][1],15);
                    printf("Descuento del producto: 15\n");
                    }
                }
            }
            
        //Anadiendo el producto al carro de compras y comprobando la respuesta
        do{
        printf("Quieres anadir este producto a tu carrito de compras? (Y/N) ");
        scanf(" %c", &respuesta);
        }while(2 == sino(respuesta));
     }while(respuesta == 'n' || respuesta == 'N');
        if(respuesta == 'y' || respuesta == 'Y'){
            listacompra[colector][0] = idprompt;
            listacompra[colector][1] = precio;
            colector = colector + 1;
            }
    do{     
    printf("Quieres seguir comprando? (Y/N) ");
    scanf(" %c", &respuesta);
    printf("\n");
    if(0 == sino(respuesta)){
        
        for(int i=0; i<colector; i++){
            
            printf("\nID del producto %d: %d\n", i+1, listacompra[i][0]);
            printf("Precio del producto %d: %d\n", i+1, listacompra[i][1]); 
                
            }
        }
    if(1==sino(respuesta)){
        comprobante = 1;
        }
    }while(2==sino(respuesta));
 }while(comprobante==1);
 
 for(int i=0; i<colector; i++){
     total = total + listacompra[i][1];
     }
 printf("\n\nTotal a pagar: %d\n", total);
 printf("Ingrese monto recibido: ");
 scanf("%d", &monto);
 printf("\n");
 if(monto<total){
     printf("%d faltantes.", total-monto);
     }
 if(monto>=total){
     printf("Vuelto: %d", monto-total);
     }

    
return 0;
}

 int numeroRandom(){
int random;
random = rand();
if(random>3000 && random<10000){
    random = random / 5;
    }
if(random<100){
    random = random * 3;
    }
if(random>10000){
    random = random / 13;
    }
return random;
}

int rangoValido(int Rangomin, int Rangomax, int i){
if(i>=Rangomin && i<=Rangomax){
    return 1;
    }else{return 0;}
}

int descuento(int num, int descuento){
num = num * (descuento / 100);
return num;
}

//Si la funcion sino() regresa 0, entonces la respuesta fue no. Si es 1, la respuesta es si. Y si 
es 2, la respuesta es invalida.

int sino(char sino){
if(sino=='y' || sino=='Y'){
    return 1;
    }
if(sino=='n' || sino=='N'){
    return 0;
    }
else{return 2;}
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
Groxil
  • 1
  • Does this solve your problem?? https://stackoverflow.com/a/67742954/17163713 – xBatmanx Nov 13 '21 at 19:33
  • 1
    Short answer: No. There is no reasonable way to make `scanf` do the right thing in the face of bad input. IMO it is not even worth the effort to try. If you've got a program that uses `scanf`, and if it works well for correct input, you should be content with that. If you want to write code that deals cleanly and gracefully with bad input, it's time to learn how to do input using something other than `scanf`. – Steve Summit Nov 13 '21 at 19:49
  • See also [What can I use for input conversion instead of scanf?](https://stackoverflow.com/questions/58403537) See also [this answer](https://stackoverflow.com/questions/2979209/using-fflushstdin/58884121#58884121). – Steve Summit Nov 13 '21 at 19:54
  • It is unsafe to use `scanf` without checking the return value. See the following link for further information: [A beginners' guide away from scanf()](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) Also, for line-based user input, I recommend that you use the function `fgets` instead of `scanf`. For an example, see [this answer of mine to another question](https://stackoverflow.com/a/69636446/12149471). Feel free to simply copy my function `get_int_from_user` from that answer, which performs extensive input validation. – Andreas Wenzel Nov 13 '21 at 19:54

0 Answers0