0

fairly new programmer here just trying to understand if there is a better way to do this and hoping to get some feedback.

TL;DR: Is there a better way to clear stdin when looking for a specific input?

For some background, I've been learning C for the past 3 weeks and scanf() has been our "go to" function for user input. After looking around for answers to this question, I'm beginning to learn that scanf() is not always preferred.

In this part of the assignment that I'm working on, I created this while loop that is supposed to run while the user input is a nonzero, positive integer. It took a while, but to get to this point I now understand that if a string is inputted instead of an integer when scanf("%d", &variable); is assigned while using leads to an infinite loop as stdin does not get cleared.

I tried to solve this problem by checking to see the return of the scanf() functions, and running the loop while the return is equal or less than 0 (which would mean that the scanf() function broke and did not return anything since it saw a char instead of an int).

The thing is, the code seems to work great until we encounter one scenario, which is where we have characters followed by an integer.

For example:

  • Input = 1
    • program runs with no issues
  • Input = string
    • program runs loop, asks for new valid input
  • Input = string string
    • program runs loop, asks for new valid input
  • Input = 123string
    • program proceeds, but then next loop with an int scanf() is infinite. 123 is stored as an int to variable.

My current understanding of the issue is that scanf() reads the integers until we get to the characters and then "string\n" gets stored to stdin, creating an infinite loop in the next part. To solve the issue, I added a fflush(stdin); before the next integer scanf() loop which seems to work.

So my question is: Would somebody be willing to show me some other ways to do this other than adding a fflush(stdin); line before every int scanf() loop? I'm sure there are better ways but I don't rightly know who to ask and the internet seemed like a good resource. Thank you.

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

int main()
{
    int squareLen = 0;
    int numColors = 0;
    int infiniteLoopStop;

    // Asks for user input of desired Square Length
    printf("Please enter the finished side length (in inches) of one square.\n> ");
    while (squareLen < 1) {
        infiniteLoopStop = scanf("%d", &squareLen);
        if (infiniteLoopStop <= 0 || squareLen < 1) {
            printf("\nInvalid input. Enter a nonzero, positive integer.\n> ");
            fflush(stdin);
        }
    }

    // Temporary solution to problem
    fflush(stdin);

    // Asks for int input of colors and loops while number of colors is not 2 or 3
    printf("How many colors are you using? Enter 2 or 3.\n> ");
    while (numColors < 2 || numColors > 3) {
        infiniteLoopStop = scanf("%d", &numColors);
        if (infiniteLoopStop <= 0 || numColors < 2 || numColors > 3) {
            printf("Invalid, please enter 2 or 3.\n> ");
            fflush(stdin);
        }
    }

    printf("\n");

    return 0;
}


  • 4
    ... **or** read a _line_ into a _string_ with `fgets()` and then process the string with `sscanf(), strto*()`, etc. Don't use `scanf()`. – chux - Reinstate Monica Jul 17 '21 at 04:16
  • I strongly suggest using POSIX's `getline` (if you don't have POSIX, it's easy to implement in terms of `fgets` + `realloc`), followed by `sscanf` or perhaps something else like `strtok_r` or `strtoul`. – o11c Jul 17 '21 at 04:19
  • [Alternatives to scanf()](https://stackoverflow.com/questions/58403537/what-can-i-use-for-input-conversion-instead-of-scanf) You can use one of the functions mentioned here to take input line by line as string and go through that string to extract digits. – Daoist Paul Jul 17 '21 at 04:41
  • `fflush(stdin);` is undefined behaviour. Don't do that. – n. m. could be an AI Jul 17 '21 at 07:50
  • See [Using `fflush(stdin)`](https://stackoverflow.com/q/2979209/15168) for a nuanced discussion of the ins and outs of using `fflush(stdin)`. – Jonathan Leffler Jul 19 '21 at 23:37

0 Answers0