Eusebio Garcia
Eusebio Garcia

Reputation: 31

scanf doesn't work (integer)

When I execute my code, scanf("%d", &n); don't scan anything, I mean, if I introduce any number it doesn't do anything, regardless of the numbers I introduce.

void testEsPrimo() {
    int n; 

    printf("Comprobando si un número es o no primo\n");
    printf("Teclee un número entero: ");
    fflush(stdout);

    scanf("%d", &n);  //<---- The problem ?

    if(esPrimo(n) == cierto){
        printf("%d es primo\n", n);
    }else{
        printf("%d NO es primo\n", n);
    }

    fflush(stdout);
}


Logico esPrimo(int n){
int divisor;
int esPrimox;
for(divisor = 2; sqrt(n); divisor++) {
    if(n <= 0) {
        return falso;
    } else {
        if(n%divisor == 0) {
            esPrimox = 0;
        } else {
            esPrimox =1;
        }
    }

}
if(esPrimox == 1) {
    return cierto;
}

return falso;

}

This is my esPrimo code that is about decide if a number is prime or not.

typedef enum {falso, cierto} Logico;

and this is Logico, defined in a .h file

PD: This are my first steps on C so my code might be bad. PD2: Excuse me for my bad English I'm not native and my English isn't really good.

Upvotes: 2

Views: 593

Answers (2)

Shondeslitch
Shondeslitch

Reputation: 1079

Your scanf is perfect.

I think that your mistake is the loop for from esPrimo. Actually you have an infinite loop, because sqrt(n) has always the same value and it isn't a boolean expression.

Change your loop:

for(divisor = 2; sqrt(n); divisor++) {
        if(n <= 0) {
            return falso;
        } else {
            if(n%divisor == 0) {
                esPrimox = 0;
            } else {
                esPrimox =1;
            }
        }

    }

for this:

 for(divisor = 2; divisor < sqrt(n); divisor++) {
            if(n <= 0) {
                return falso;
            } else {
                if(n%divisor == 0) {
                    esPrimox = 0;
                } else {
                    esPrimox =1;
                }
            }

        }

But then you have a problem when you know that your number is not prime: you have to finish the loop. You can do this:

for(divisor = 2; divisor < sqrt(n); divisor++) {
            if(n <= 0) {
                return falso;
            } else {
                if(n%divisor == 0) {
                    esPrimox = 0;
                } else {
                    esPrimox =1;
                    break;
                }
            }

        }

But if you can avoid using breakinside a loop for, don't use that. With complicated algorithms you have a clean code with that, but when you read a loop for, usually your understand that the loop do a exactly number of iterations. If you have another flag to end the loop, use while.

While (divisor < sqrt(n) && esPrimox == 0){
            if(n <= 0) {
                return falso;
            } else {
                if(n%divisor == 0) {
                    esPrimox = 0;
                } else {
                    esPrimox =1;
                }
            }

        }

Upvotes: 4

Klas Lindb&#228;ck
Klas Lindb&#228;ck

Reputation: 33273

There are 2 main problems in esPrimo.

First, the for loop will not terminate:

for(divisor = 2; sqrt(n); divisor++) {

Change the condition to:

for(divisor = 2; divisor <= sqrt(n); divisor++) {

Second is in the logic. If you find that n is not a prime, you need to break the loop or the function will always return true. You could do it either with the break statement or by checking the value of esPrimox in the loop condition.

Here's how to do it using break:

for(divisor = 2; divisor <= sqrt(n); divisor++) {  /* fixed loop condition */
    if(n <= 0) {
        return falso;
    } else {
        if(n%divisor == 0) {
            esPrimox = 0;
            break;        /* break the loop */ 
        } else {
            esPrimox =1;
        }
    }
}

Upvotes: 1

Related Questions