Crysishy
Crysishy

Reputation: 57

How to let scanf() keep reading integer inputs unless a character is input?

I'm trying to do a program that reads inputs from user and determine whether the integer is Fibonacci or not.

The program should print out num is fib or num is not fib where num is a positive integer;

if the input is a non-positive number, the program should not produce any output (but it should produce an error mesage on stderr) and it should keep prompting;

if the input contains any characters, the program should not produce any output (but it should produce an error mesage on stderr) and then exit.

This is the expected results:

1 2 3 4 5
1 is fib
2 is fib
3 is fib
4 is not fib
5 is fib

(keep prompting inputs)

1 -2 3 -4 5
1 is fib
Error: input value -2 is not positive
3 is fib
Error: input value -4 is not positive
5 is fib

(keep prompting inputs)

1-23-45
1 is fib
Error: input value -23 is not positive
Error: input value -45 is not positive

(keep prompting inputs)

12a
12 is not fib
Error: input is not a number

I was able to check the first input number, but when it's done, the program exits itself. How do I let the scanf() know when to keep reading and when to exit?

This is my code

int main() {
    int num, x, y, z;

    while (scanf("%d", &num) > 0) {
        if (num <= 0) {
            fprintf(stderr, "Error: input value %d is not positive\n", num);
            return -1;
        } else {
            x = 0;
            y = 1;
            z = x + y;
            while (z < num) {
                x = y;
                y = z;
                z = x + y;
            }
            if (z == num) {
                printf("%d is fib\n", num);
            } else {
                printf("%d is not fib\n", num);
            }
            return 0;
        }
    }
    return 0;
}

Upvotes: 1

Views: 1314

Answers (2)

Pooya
Pooya

Reputation: 6126

This is because you return from all of the conditions in your program. Try the following without return 0 in the else clause:

int main(){
    int num,x,y,z;

    while (scanf("%d", &num) > 0){
        if (num <= 0){
            fprintf(stderr, "Error: input value %d is not positive\n", num);
        }
        else {
            x = 0;
            y = 1;
            z = x + y;
            while (z < num){
                x = y;
                y = z;
                z = x + y;
            }
            if (z == num){
                printf("%d is fib\n", num);
            }
            else {
                printf("%d is not fib\n", num);
            }
        }
    }
    if(feof(stdin))
        return 0;
    fprintf(stderr, "Error: input value is not a number\n");
    return 1;
}

Upvotes: 1

chqrlie
chqrlie

Reputation: 144685

You currently exit the main function when scanf returns less than 1. If a character is present in stdin that does not begin a number, such as a, scanf("%d", &num) will return 0, you will exit the program, but without a message. You also exit with return 0; after the first result, which is incorrect.

You must change to logic when a number cannot be parsed and only exit silently at end of file, when scanf returns EOF:

#include <stdio.h>

int main(void) {
    int status, num, x, y, z, exit_code = 0;

    while ((status = scanf("%d", &num)) >= 0) {
        if (status == 0) {
            fprintf(stderr, "Error: input is not a number\n");
            return 1;
        }
        if (num <= 0) {
            fprintf(stderr, "Error: input value %d is not positive\n", num);
            exit_code = 1;
            continue;
        }
        x = 0;
        y = 1;
        z = x + y;
        while (z < num) {
            x = y;
            y = z;
            z = x + y;
        }
        if (z == num) {
            printf("%d is fib\n", num);
        } else {
            printf("%d is not fib\n", num);
        }
    }
    return exit_code;
}

Upvotes: 3

Related Questions