2

When I use fgets in the following piece of code without the newline character in printf , the program does not wait for my input. It seems like either using a new line character in the printf statement before OR using the flushing the stdin fixes the problem. But can someone expain what's going on and why a \n or flsuhing fixes it?

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


int main(void)

{

    char *userInput = malloc(sizeof(*userInput) * 2);

    printf("Enter a character:"); // This leads to an issue where fgets does not wait for an input

    /* 
    Using either of the below statements fixes it though 

    printf("Enter a character:\n");

    OR 

    fflush

    */


    fgets(userInput, 2, stdin);

    printf("The character you entered is: %c \n", userInput[0]);

}

Thanks!

aj31
  • 87
  • 10
  • 1
    Possible duplicate of [Why does printf not flush after the call unless a newline is in the format string?](https://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin) – Vasanth Alagiriswamy Mar 24 '18 at 04:20
  • you can also have a look at https://stackoverflow.com/questions/11575102/issue-in-c-language-using-fgets-after-printf-as-fgets-runs-before-printf – Vasanth Alagiriswamy Mar 24 '18 at 04:21
  • 1
    regarding: `char *userInput = malloc(sizeof(*userInput) * 2);` This allocates ( on a 32 bit architecture ) 8 bytes. However, when reading from `stdin` (and similar sources ) a size around 1024 bytes would be much much better. Suggest: `char *userInput = malloc( 1024 );` and always check (!=NULL) the returned value to assure the operation was successful. Then the call to `fgets()` should be `if( fgets( userInput, sizeof( userInput ), stdin ) == NULL ) { // handle error and exit } – user3629249 Mar 24 '18 at 04:29
  • @user3629249 Thanks for the input, but if my program only needs to read 2 characters from stdin, are there still any advantages to allocating 1024 bytes? – aj31 Mar 24 '18 at 04:31
  • 1
    If you want the user to enter 2 characters, then 1) ask for two characters, 2) check to assure that the user entered 2 characters, not just a single character and a newline or just a newline. 3) in a typical use of `fgets()` a newline will be included in the input AND a NUL byte will be appended to the user input. So the desired input sizing would be 4 characters I.E. `\n\0` There is no need to call `malloc()` for 4 characters, just use something like: `userInput[4];` and `fgets( userInput, sizeof( userInput ), stdin );` – user3629249 Mar 24 '18 at 04:47
  • @user3629249 Thanks, that makes a lot of sense. – aj31 Mar 24 '18 at 04:50

2 Answers2

1

For all C runtimes I'm aware of stdout is line buffered when connected to a terminal (and block buffered when connected to anything else), so output is only flushed to the screen when a newline is output, or fflush is used to explicitly flush the buffer. Without the newline (or an fflush(stdout) call), the printf output goes to the buffer, but never gets flushed to the screen.

Obviously, fflush(stdout) fixes this, as does actually outputting a newline. You could also globally disable buffering for stdout with the setvbuf function, though that risks slowing I/O.

ShadowRanger
  • 108,619
  • 9
  • 124
  • 184
0

this is a proper way to have the user enter a single character then echo that char to the terminal

#include <stdio.h>


int main(void)
{
    int userInput;

    printf("Enter a character:\n");

    if( (userInput = getchar() != EOF) )
    {
        printf("The character you entered is: %c \n", userInput);
    }
}

Your comments discuss the user entering two characters, BUT your code is only looking for 1 char (as is shown by your prompt to the user)

user3629249
  • 15,593
  • 1
  • 16
  • 17
  • please look at your code once and edit `if( (userInput = getchar() != EOF) )` line as it will always prints either 1 or 0 instead of character entered – Vasanth Alagiriswamy Mar 25 '18 at 04:34