2

I have written the below small code with several conditions on number entered by the user

#include<stdio.h>
int main()
{
    int userInput;
    while(1)
    {

        printf("Press '1':To Print\n");
        scanf("%d",&userInput);
        if(userInput==1)
        {
            printf("ABCD\n");
        }
        else
        {
            printf("WARNING:Pressed invalid key");
        }
    }
}

When I press any number then it works fine, but when I press up arrow/any character key and press enter the loop runs infinite times.

Why is this happening and is there any way to prevent it?

Abhishek Gangwar
  • 1,697
  • 3
  • 17
  • 29

3 Answers3

2

You're not checking whether scanf failed. May something like this help?

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

void printHelp(bool afterInvalid) {
    if(afterInvalid)
            fprintf(stderr, "\nInvalid input, try again!\n");

    printf("Press 1 to print\nPress 3 to break\nInput: ");
}

int main() {
    while(1) {
            int userInput;

            printHelp(false);
            if(scanf("%d", &userInput) == 0) {
                    char ch;
                    bool reachedNewline = false;
                    do {
                            if(reachedNewline) {
                                    printHelp(true);
                                    reachedNewline = false;
                            }

                            ch = getchar();
                            if(ch == '\n')
                                    reachedNewline = true;
                    } while(!isdigit(ch));
                    ungetc(ch, stdin);

                    continue;
        }

            if(userInput == 1)
                    printf("ABCD\n");
            else if(userInput == 3) {
                    printf("Breaking!\n");
                    break;
            } else
                    printHelp(true);
    }

    return 0;
}
3442
  • 8,248
  • 2
  • 19
  • 41
1

this makes it an infinite loop that keep asking to print..

#include<stdio.h>
    int main()
    {
        int userInput;
        while(1!=EOF)
    {

        printf("Press '1':To Print\n");
        scanf("%d",&userInput);
        if(userInput==1)
        {
            printf("ABCD\n");
        }
        else
        {
            printf("WARNING:Pressed invalid key");
        }
    }
}
S.Lordan
  • 23
  • 1
  • 4
1

Check the return value from scanf("%d"... and consume the non-numeric input as needed.

#include<stdio.h>

int main(void) {  // Add void
    int ch = 0;
    while (ch != EOF) {
        int userInput;
        printf("Press '1':To Print\n");
        // Expect 0, 1 or EOF to be returned 
        int fields_scanned = scanf("%d",&userInput);
        if (fields_scanned == 1) {
            printf("ABCD %d\n", userInput);
        }
        else if (fields_scanned == 0) {
            printf("WARNING:Pressed invalid key\n");
        }
        // Consume remaining characters in the line
        while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
            ;
        }
    }
    return 0;  // Not required, yet good practice.
}

All in all, recommend using fgets()/other code instead of scanf()

#define INT_MAX_SIZE (sizeof (int) * CHAR_BITS /3 + 3)

fputs(Prompt, stdout);
char buf[INT_MAX_SIZE*2 +1];  // I like 2x expected size, no need to be stingy here.
if (fgets(buf, sizeof buf, stdin) == NULL) break;  // No more input or error
// Use sscanf() or strtol(), etc
if (sscanf(buf, "%d", &userInput) == 1) {
  ; // Success
} else {
  ; // Failure
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256