4

This program runs fine.

int main()
{
    {
        printf("Type something:\n");
        char* message = malloc(64 * sizeof(char));
        fgets(message, 64, stdin);
        printf("message ist : %s\n", message);
        free(message);
    }
}

But when i run the following program, It doesnt let me write anything, it prints "message ist: "

int main()
{
    char action;

    while(action!='e')
    {
        printf("print a line: p\n");
        printf("End Program:  e\n");

        action = getc(stdin);

        if(action == 'p')
        {
            fflush(stdin);
            printf("Type something:\n");
            char* message = malloc(64 * sizeof(char));
            fgets(message, 64, stdin);
            printf("message ist : %s\n", message);
            free(message);
        }
        else if(action == 'e')
        {
            printf(" Program ended successfully\n");
            exit(0);
        }
    }
}

Does anyone have explaination why it let me input in first program, and why it didn't let me input in second program?

I tried to flush the keyboard inputs, it didn't work. I tried with getline() instead of fgets(), same result.

I would be thankful for any ideas and explaination.

klutt
  • 30,332
  • 17
  • 55
  • 95
Cathen
  • 45
  • 3
  • Now it's time to start debugging. Have investigated the value of `action`? And, btw, `fflush(stdin)` is undefined behavior. – klutt Nov 12 '19 at 08:32
  • 1
    when you type "p" you realy type "p". That "" is the only character that `fgets()` sees. – pmg Nov 12 '19 at 08:33
  • You may want to initialize `action` rather than comparing it to an unknown value: `char action = 0;` – pmg Nov 12 '19 at 08:35
  • 1
    @klutt: `fflush(stdin);` is indeed UB on implementations without extensions. The Windows library, for example, extends C by (possibly among other things) defining `fflush(stdin);`. I never use it though, and I think relying needlessly on an extension is bad. – pmg Nov 12 '19 at 08:38
  • @pmg If they know that they are using an extension, then they can ignore such advices. If they don't well, then it's a good thing to tell them. :) – klutt Nov 12 '19 at 09:36

2 Answers2

1
#include <stdio.h>

void customFlush()
{
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main()
{
    char action;
    char message[64] = { };

    while(action != 'e')
    {
        printf("---------\nCommands:\n'p' for print a line\n'e' for end program\n\nType a command: ");
        action = getc(stdin);
        // Exclude unnecessary chars (<Enter> and so on)
        customFlush(); // or fseek(stdin, 0, SEEK_END);

        if (action == 'p')
        {
            memset(message, 0, sizeof(message));
            printf("\nType something:\t");
            fgets(message, 64, stdin);
            printf("\nTyped message:\t%s\n", message);
            // Here is also possible place for calling customFlush or fseek()
        }
    }
    printf("Program ended successfully\n");
}
Yeheshuah
  • 1,216
  • 1
  • 13
  • 28
0

Seems like fflush(stdin) (it is undefined as already mentioned) does not work properly. The problem is the '\n' which is still in the buffer and has to be removed. Otherwise fgets is called, finds the '\n' in the buffer (which marks the end of the input) and continues with the program.

Try this instead:

    // fflush(stdin);
    while (getchar() != '\n');
    printf("Type something:\n");
    char* message = (char*) malloc(64 * sizeof(char));
    fgets(message, 64, stdin);
    printf("message is : %s\n", message);
    free(message);

What also works fine (but probably unintended) is an input like "p MyMessage". This prints the message indeed.

Pedro Isaaco
  • 404
  • 3
  • 10