954,479 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

User Input Problems

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

nexocentric
Junior Poster in Training
72 posts since Mar 2009
Reputation Points: 26
Solved Threads: 4
 

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.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

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....

nexocentric
Junior Poster in Training
72 posts since Mar 2009
Reputation Points: 26
Solved Threads: 4
 

Could you do something like this:

scanf( " " ); // Consume whitespace, if any (incl. newline)
  fgets( ... );
nucleon
Posting Pro in Training
478 posts since Oct 2008
Reputation Points: 163
Solved Threads: 91
 

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.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

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?

nexocentric
Junior Poster in Training
72 posts since Mar 2009
Reputation Points: 26
Solved Threads: 4
 

>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.

nucleon
Posting Pro in Training
478 posts since Oct 2008
Reputation Points: 163
Solved Threads: 91
 

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...

nexocentric
Junior Poster in Training
72 posts since Mar 2009
Reputation Points: 26
Solved Threads: 4
 

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

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You