0

When the following function is called and run, if the initial "if" condition is met, the program runs as intended; repetitively. If the initial "if" condition is not met, the program proceeds to run the else statement, but gets stuck in an endless loop.

Why?

#include <stdio.h>
#include <string.h>

int num_func();

int main()
{
    num_func();

   return 0;
}

int num_func()
{
    int num;
    char yn[1];

    printf("Please enter an integer value: ");

    if (scanf("%d", &num) == 1)

        {
            printf("The value you entered is: %d. Is this correct? ", num);
            scanf("%s", &yn);

            if (strcmp(yn, "y") == 0) {
                printf("Great! \n");
            }

            else if (strcmp(yn, "n") == 0) {
                printf(":( \n");
            }

            else {
                printf("Illegal Entry. \n");
            }
        }

    else {
        printf("You were told to put in a number!");
    }

    num_func();
}

I am also interested in finding out how to make num and yn[1] global variables so that num_func() can access them w/o having to allocate memory each run. If you could explain that, I would be grateful.

  • 1
    because you recursively call the function at the end of itself so it will repeat "forever" (or until it overflows the stack if tail recursion optimizations aren't enabled during compile). – jodag May 28 '19 at 03:19
  • But the num_func is placed outside of the if else statements, when either of those conditions are met, shouldn't the compiler run num_func from the beginning instead of looping thru the else statement? –  May 28 '19 at 03:21
  • There's no return statement in the function so it never exits early. num_func() will get called after the if or else statements are executed regardless of which condition is met. – jodag May 28 '19 at 03:23
  • I don't understand –  May 28 '19 at 03:25
  • Programs run in sequence. Why do you think that the final statement in num_func (which itself is another call to num_func) won't be executed? – jodag May 28 '19 at 03:25
  • I understand that jodag. I get that the function will run endlessly. thats what I want. I'm trying to understand why if "num_func() will get called after the if or else statements are executed regardless of which condition is met" it doesn't start from the TOP where the user is asked to enter an integer value –  May 28 '19 at 03:29
  • Oh my mistake. I misunderstood the question, I thought you were asking why in the case that the else was called the infinite loop didn't end. – jodag May 28 '19 at 03:31
  • It's not your fault, I worded it ambiguously the mistake is mine –  May 28 '19 at 03:35
  • Use a while loop around num_func rather than recursion. Thats bad form. – hookenz May 28 '19 at 03:43
  • Possible duplicate of [C: scanf for char not working as expected](https://stackoverflow.com/questions/29122166/c-scanf-for-char-not-working-as-expected) – hookenz May 28 '19 at 03:54

2 Answers2

0

Following the answer here. On invalid input stdin won't be cleared so you need to clear it yourself. Otherwise, the next time that scanf is called it will see that there is still data to be read and try to read the invalid data again.

#include <stdio.h>
#include <string.h>

int num_func();

int main()
{
    num_func();

   return 0;
}

int num_func()
{
    int num, c;
    char yn[1];

    printf("Please enter an integer value: ");

    if (scanf("%d", &num) == 1)

        {
            printf("The value you entered is: %d. Is this correct? ", num);
            scanf("%s", &yn);

            if (strcmp(yn, "y") == 0) {
                printf("Great! \n");
            }

            else if (strcmp(yn, "n") == 0) {
                printf(":( \n");
            }

            else {
                printf("Illegal Entry. \n");
                while ((c = getchar()) != EOF && c != '\n')
                    continue;
            }
        }

    else {
        printf("You were told to put in a number!\n");
        while ((c = getchar()) != EOF && c != '\n')
            continue;
    }

    num_func();
}

As far as the second question is concerned, making the variable global to save space is totally unnecessary here since the function has negligibly small stack frame already.

jodag
  • 19,885
  • 5
  • 47
  • 66
  • Do you mind explaining what's going on in these lines here? while ((c = getchar()) != EOF && c != '\n') continue; –  May 28 '19 at 03:54
  • `getchar` pops one character from the input stream `stdin` where characters are read. This loop keeps repeating until either `EOF` (a value indicating the end of the buffer has been reached) or a newline character `\n` is found, indicating the end of the an entry. In this case the left hand expression is evaluated first, ensuring `c` has been set to the next value in the buffer. – jodag May 28 '19 at 04:02
  • Okay so let me get this straight. When a non-integer value is entered into scanf and scanf is expecting an integer value, then scanf stores the non integer value as 0 until the entire program is run after which it changes the value to EOF. It makes sense why we include that in the condition for the while loop but I don't get where \n is "found" and why that's included in the condition. –  May 28 '19 at 04:26
0

Problem here was that after entering in else statement and to run scanf which is in if condition can not take input because i/o buffer is not clear and according to ur wish i have made num and yn[] global.

#include <stdio.h>
#include <string.h>

int num_func();
int num, c;
char yn[1];
int main()
{
    num_func();

    return 0;
}

int num_func()
{

    printf("Please enter an integer value: ");
    fflush(stdin);
    if (scanf("%d", &num) == 1)

        {
            printf("The value you entered is: %d. Is this correct? ", num);
            scanf("%s", &yn);

            if (strcmp(yn, "y") == 0) {
                printf("Great! \n");
            }

            else if (strcmp(yn, "n") == 0) {
                printf(":( \n");
            }

            else {
                printf("Illegal Entry. \n");

            }
        }

    else {
        printf("You were told to put in a number!\n");

    }

    num_func();
}
Rishi
  • 1
  • 1