program to detect whether only integer has been given or not goes into infinite loop

醉酒当歌 提交于 2019-12-11 01:13:21

问题


// program to detect whether only integer has been given or not
int main() {
    int a, b, s; 
    printf("Enter two proper number\n");
 BEGIN:
    s = scanf("%d %d", &a, &b); //storing the scanf return value in s
    if (s != 2) {
        printf("enter proper value\n");
        goto BEGIN;
    }
    printf("The values are %d and %d ", a, b);
}

This program to detect whether only integer has been given or not goes into infinite loop when invalid data is entered instead of asking for new values why doesn't the goto work here?


回答1:


Note that when scanf gets bad input (for example you enter cat dog) that input remains in the input buffer until you take steps to clear it out. So the loop keeps repeating and rejecting the same input which is still there.

It is simpler to use fgets and sscanf and if the scan fails, you just forget the input string and get another.

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

int main(void) {
    int a, b;
    char str[42];
    do {
        printf("Enter 2 numeric values\n");
        if(fgets(str, sizeof str, stdin) == NULL) {
            exit(1);
        }
    } while(sscanf(str, "%d%d", &a, &b) != 2);
    printf("Numbers are %d and %d\n", a, b);
}

Program session:

Enter 2 numeric values
cat dog
Enter 2 numeric values
cat 43
Enter 2 numeric values
42 dog
Enter 2 numeric values
42 43
Numbers are 42 and 43

Note that goto is poor practice in C and should be used only where there is no other way of constructing the code — which there usually is.




回答2:


There are multiple reasons scanf() can return a value different from 2:

  • there is pending input that cannot be converted according to the conversion specification. For example if there is an A pending in the input stream, the %d conversion fails and the A stays in the input stream. Your code just keeps trying this conversion and will never stop. You should read and discard the offending input before re-trying.
  • the input stream has had a read error or hit the end of file. If at least one conversion succeeded, the number of successful conversions is returned, otherwise EOF is returned. If EOF is returned, there is no point trying again since no more input will be available.
  • Note also that it is considered bad style to use goto for constructions that are better expressed with flow control statements such as while and for.

Here is a corrected version:

#include <stdio.h>

// program to detect whether only integer has been given or not
int main() {
    int a, b, s, c;

    printf("Enter two proper numbers: ");
    for (;;) {
        s = scanf("%d%d", &a, &b); //storing the scanf return value in s
        if (s == 2) // conversions successful
            break;
        if (s == EOF) {
            printf("unexpected end of file\n");
            return 1;
        }
        /* discard the rest of the input line */
        while ((c = getchar()) != EOF && c != '\n')
            continue;
        printf("Invalid input. Try again: ");
    }
    printf("The values are %d and %d\n", a, b);
    return 0;
}



回答3:


scanf returns the number of characters. As a result, s will be equal to the number of characters you have written is 2, then your loop will stop. The reason this runs infinitely many times is that the number of characters you have entered differed from 2. Print s to see what value it holds and you will get more information.



来源:https://stackoverflow.com/questions/52795781/program-to-detect-whether-only-integer-has-been-given-or-not-goes-into-infinite

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!