I was making a dos based text game and needed user input. I looked through the forums and found the thread on safe user input, which would be using fgets() instead of gets().

The first problem I ran into was that stdin always had '\n' in the buffer, so it wouldn't wait for user input. I read online that stdin has to be cleared of all '\n' characters before calling it, so I used scanf() to remove the newline characters from stdin.

I am now stumped with why the following code doesn't get the user's input.

/* clear stdin */
	i_eof = scanf("%*[^\n]"); /* read and discard all non-newlines */
	if ( i_eof != EOF)
	{
		i_eof = scanf("%*c");
	}

	/* get user input */
	fgets( m_c_inputBuffer_ary, i_InputMax, stdin );

I have attemped discarding the scanf calls and using fflush(stdout) followed by fflush(stdin), but that brings me to the same problem as before. the fgets() call won't wait for user input because of a newline character in stdin.

Placing a fflush(stdin) call after the scanf() calls and before the fgets() calls also yields the result of pausing for user input, but getting nothing as the value of the input.

Interested in finding out what's going on.

Thanks in advanced

Recommended Answers

All 8 Replies

There is no ansi c standard way of flushing the input stream. fflush(stdin) is compiler specific becaue fflush() is only guaranteed to work on output streams such as stdout.

If you want a non-standard way to do it you could use fflush(stdin) or functions from conio.h such as

while(_kbhit() ) // while more keys in the keyboard
    getche(); // remove the key

>>The first problem I ran into was that stdin always had '\n' in the buffer
That normally happens only after calling scanf() to get numeric input. fgets() will remove the '\n' and append it to the end of the input buffer if the input buffer is large enough to hold it.

There is no ansi c standard way of flushing the input stream. fflush(stdin) is compiler specific becaue fflush() is only guaranteed to work on output streams such as stdout.

If you want a non-standard way to do it you could use fflush(stdin) or functions from conio.h such as

while(_kbhit() ) // while more keys in the keyboard
    getche(); // remove the key

>>The first problem I ran into was that stdin always had '\n' in the buffer
That normally happens only after calling scanf() to get numeric input. fgets() will remove the '\n' and append it to the end of the input buffer if the input buffer is large enough to hold it.

Hmm, I didn't do any calls to scanf() before calling fgets().... I'll post the original function. it's pretty short.

char * Menu::GetUserInput_func( char * c_promptText_ptr, int i_InputMax )
{

	/* initializations */
	memset( m_c_inputBuffer_ary, 0x00, sizeof(m_c_inputBuffer_ary) );

	/* print the input prompt to the screen */
	printf( "%s", c_promptText_ptr );

	/* get user input */
	fgets( m_c_inputBuffer_ary, i_InputMax, stdin );
	return m_c_inputBuffer_ary;

}

If i try and call this function the program just loops....

Could you do something like this:

scanf( " " ); // Consume whitespace, if any (incl. newline)
  fgets( ... );

The problem may be in another function. Remember, the keyboard buffer is global to the entire program, not just one function.

Also, that function should probably strip off the '\n' character at the end of the buffer, otherwise your program may not process the contents of the buffer correctly.

Could you do something like this:

scanf( " " ); // Consume whitespace, if any (incl. newline)
  fgets( ... );

That solution is basically like my original solution, and leaves me with input that never gets saved in the buffer that i made available for it.

The problem may be in another function. Remember, the keyboard buffer is global to the entire program, not just one function.

Also, that function should probably strip off the '\n' character at the end of the buffer, otherwise your program may not process the contents of the buffer correctly.

I'll go ahead and search my code for any functions that may be causing input problems. If i have any problems after that, I'll post my findings on here. I did however try my function using gets() instead, and I had no problems... I was just interested in using something safer...if gets() works does that mean that fgets() should work as well?

>That solution is basically like my original solution, and leaves me with input that never gets saved in the buffer that i made available for it.

Actually it isn't like your original solution. Differences:
1. yours consumes any characters, not just whitespace
2. yours consumes a line even when you don't want it to

Mine only consumes initial whitespace (incl. newline) leaving any non-whitespace to be picked up by the fgets. That doesn't mean it does what you want though!

Probably the best solution is to read all input with fgets and deal with the string so read (perhaps with sscanf). You could wrap fgets in a function that does two things:
1. Ensures the string is not only whitespace (if that's not allowed)
2. Removes the '\n' (if any) from the end of the buffer.

I found out what the problem was. The fflush, and stdin clearing methods that I was using and the one that nucleon suggested work just fine. The reason that I wasn't getting anything from fgets is that fgets adds a null terminator to the end of the string. I had the buffer size set to 1, which would mean there would only be room for the null terminator. I guess slip ups like mine happen sometimes...

Note that fgets() will also append '\n' to the end of the string if it appears in the input stream.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.