Why is scanf() causing infinite loop in this code?

后端 未结 16 1445
日久生厌
日久生厌 2020-11-21 06:20

I\'ve a small C-program which just reads numbers from stdin, one at each loop cycle. If the user inputs some NaN, an error should be printed to the console and the input pro

相关标签:
16条回答
  • 2020-11-21 07:04

    On some platforms (especially Windows and Linux) you can use fflush(stdin);:

    #include <stdio.h>
    
    int main(void)
    {
      int number, p = 0, n = 0;
    
      while (1) {
        printf("-> ");
        if (scanf("%d", &number) == 0) {
            fflush(stdin);
            printf("Err...\n");
            continue;
        }
        fflush(stdin);
        if (number > 0) p++;
        else if (number < 0) n++;
        else break; /* 0 given */
      }
    
      printf("Read %d positive and %d negative numbers\n", p, n);
      return 0;
    }
    
    0 讨论(0)
  • Good evening. I've recently been through the same problem and i found a solution that might help a lot of guys. Well, actually the function "scanf" leaves a buffer at memory ... and that's why the infinite loop is caused. So you actually have to "store" this buffer to another variable IF your initial scanf contains the "null" value. Here's what i mean:

    #include <stdio.h>
    int n;
    char c[5];
    main() {
        while (1) {
            printf("Input Number: ");
            if (scanf("%d", &n)==0) {  //if you type char scanf gets null value
                scanf("%s", &c);      //the abovementioned char stored in 'c'
                printf("That wasn't a number: %s\n", c);
            }
            else printf("The number is: %d\n", n);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:08

    Hi I know this is an old thread but I just finished a school assignment where I ran into this same problem. My solution is that I used gets() to pick up what scanf() left behind.

    Here is OP code slightly re-written; probably no use to him but perhaps it will help someone else out there.

    #include <stdio.h>
    
        int main()
        {
            int number, p = 0, n = 0;
            char unwantedCharacters[40];  //created array to catch unwanted input
            unwantedCharacters[0] = 0;    //initialzed first byte of array to zero
    
            while (1)
            {
                printf("-> ");
                scanf("%d", &number);
                gets(unwantedCharacters);        //collect what scanf() wouldn't from the input stream
                if (unwantedCharacters[0] == 0)  //if unwantedCharacters array is empty (the user's input is valid)
                {
                    if (number > 0) p++;
                    else if (number < 0) n++;
                    else break; /* 0 given */
                }
                else
                    printf("Err...\n");
            }
            printf("Read %d positive and %d negative numbers\n", p, n);
            return 0;
        }
    
    0 讨论(0)
  • 2020-11-21 07:13

    I had similar problem. I solved by only using scanf.

    Input "abc123<Enter>" to see how it works.

    #include <stdio.h>
    int n, num_ok;
    char c;
    main() {
        while (1) {
            printf("Input Number: ");
            num_ok = scanf("%d", &n);
            if (num_ok != 1) {
                scanf("%c", &c);
                printf("That wasn't a number: %c\n", c);
            } else {
                printf("The number is: %d\n", n);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:14

    scanf consumes only the input that matches the format string, returning the number of characters consumed. Any character that doesn't match the format string causes it to stop scanning and leaves the invalid character still in the buffer. As others said, you still need to flush the invalid character out of the buffer before you proceed. This is a pretty dirty fix, but it will remove the offending characters from the output.

    char c = '0';
    if (scanf("%d", &number) == 0) {
      printf("Err. . .\n");
      do {
        c = getchar();
      }
      while (!isdigit(c));
      ungetc(c, stdin);
      //consume non-numeric chars from buffer
    }
    

    edit: fixed the code to remove all non-numeric chars in one go. Won't print out multiple "Errs" for each non-numeric char anymore.

    Here is a pretty good overview of scanf.

    0 讨论(0)
  • 2020-11-21 07:15

    try using this:

    if (scanf("%d", &number) == 0) {
            printf("Err...\n");
            break;
        }
    

    this worked fine for me... try this.. the continue statement is not appropiate as the Err.. should only execute once. so, try break which I tested... this worked fine for you.. i tested....

    0 讨论(0)
提交回复
热议问题