Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

get only one char from input with cin

Status
Not open for further replies.

muthuivs

Technical User
Jan 30, 2006
36
0
0
CA
I have my program done but I am trying to clean up for user fat fingering! I have a char defined. but when the cin from command line happens I want the program to only read 1 charachter since the rest of the charachters spoil my other cins. Any suggestions ? Here is an example of what I am doing:

int main()
(
char response;
string filename;

//I only want it to read a Y or N or any other single //characther
cout<<"Enter Response:";
cin>>response;

cout<<Enter filename;
cin>>filename;


}

This project never seem to be over, I have everything done except these little house cleaning before using issues!! PLease help...I need to finally get some sleep :)

MuthuIVS

 

Here is what I would do.. However this is not in the C++, but just ansi C.

char response;
char filename[max_filename_len];

response = (char)getchar();
fflush(stdin);
if(response == 'Y') {
fgets(filename, max_filename_len, stdin);
}


next, for you with c++ you can just add the fflush(stdin) after your cin. this will clear the keyboard buffer of anything that has not been read.

cout<<"Enter Response:";
cin>>response;
fflush(stdin);

Also in doing all of this you really need to do error checking if you have not already otherwise you response and/or filename could be fubar too..

 
Thanks a million. I was trying all sorts of stuff like cin.ignore(), cin.clear() and many many more. Appreciate it!!!


MuthuIVS
 
If you're only using Windows, you could also use getch() or getche() instead of getchar().

getchar() requires you to enter a character and press enter. getch() or getche() don't require enter.
 
I don't believe you should be using fflush(stdin). I believe the behavior is undefined. It would be better to use something that is standard and guaranteed to work (on standards compliant compilers).

In C++ you clear all unwanted characters from the buffer with ignore():
Code:
#include <limits>

...

cin.ignore(numeric_limits<streamsize>::max(), '\n');
 
Earlier today, I almost posted, as uolj pointed out, that [tt]fflush[/tt] is undefined on input streams, and that it would be a bad idea to use it.

Then I checked MSDN:
MSDN said:
The fflush function flushes a stream. If the file associated with stream is open for output, fflush writes to that file the contents of the buffer associated with the stream. If the stream is open for input, fflush clears the contents of the buffer.
Since Microsoft defined the behavior of its [tt]fflush[/tt] on input streams, I can't see any problem with using it for a Visual C++ project.

Of course, you should know that in the C Standard, using [tt]fflush[/tt] on an input stream most certainly is undefined. If your code relies on this Microsoft-specific behavior, you won't be able to trust it to run correctly (or at all) on any other platform.
 


Actually I need the program to be portable so I will have to change from using fflush(stdin). Thanks for the advice, I'll try to make it work.

AM
 
How do I use the cin.ignore in my example ? I am doing something wrong and it is still reading the extra charachters.

AM
 
Actually fflush is ANSI C
It is portable to 'ANY' ANSI C platform, including Unix(s), Mac and all versions of Windows. There probably are a few that dont follow ANSI standards but they are a rare few.
 


Cool...Then I am done!! Thanks Everyone!! I love this forum, the educational values are boundless!!
 
Mixing input methods (in either C or C++) always ends up leading to one sort of difficulty or another. A new line here, an uncoverted character there, a few extra characters of bad input, or deliberate buffer overflow attacks and your code has to cope with them all.

Since you can't know what the user will type, I go for always inputting a string from the user (in the case of C, this means fgets), then validating what they typed using whatever seems appropriate.

At least then, you know the input stream will remain in a consistent state, and you can separate the 'input' errors from the 'conversion' errors.

--
 
lotharius said:
Actually fflush is ANSI C
It is portable to 'ANY' ANSI C platform, including Unix(s), Mac and all versions of Windows. There probably are a few that dont follow ANSI standards but they are a rare few.
As was already pointed out, fflush is standard C, but using it on input streams is not portable. It is undefined.
muthuivs said:
How do I use the cin.ignore in my example ? I am doing something wrong and it is still reading the extra charachters.
Show your code, tell us your input, and tell us what output you expect, and we can tell you what is happening that is wrong.
muthuivs said:
Cool...Then I am done!! Thanks Everyone!! I love this forum, the educational values are boundless!!
Unfortunately not all practices are good, so you have to be careful. Besides not being portable, the issue brought up by Salem about mixing input methods is another danger to your code working correctly if you use fflush. Just a little more effort to get the cin.ignore() solution working and you will have a much safer end result.
 

OK...Here is what I am trying to do

#include....

int main()
{

char response;
string strfilename;


cout<<"Do you want to run another batch (Y/N) : ";
cin>>response;
response = toupper(response);

if ((response != 'Y') && (response != 'N'))
{
do{
cin>>response;
response = toupper(response);
cout<<"\nWrong Again---Try Again :");
} while((response != 'Y') && (response != 'N'))
}


The problem is lets say the user Enters "BOO"--Unlikely but I don't give people too much credit! :) I get the folllowing output:

Do you want to run another batch (Y/N) : BOO
Wrong Again---Try Again :
Wrong Again---Try Again :
Wrong Again---Try Again :

It is fixed with fflush(stdin) since it clears the stuff the compiler doesn't use, but any ways I only want it to read the 'B' and not the 'O' and the other 'O'. Do i make sense ? I know it may be overkill but I just want the program to Run pretty especially since it took a lot of effort making it work in the first place. Suggestions would be deeply appreciated.

MuthuIVS
 
You should probably post the code that doesn't work. Replace fflush(stdin) with this:
Code:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
And add #include <limits> to you #includes. If that doesn't work, copy and paste the actual program, with all the includes and without the syntax errors. Also, please put the code in [code][/code] tags so it is easier to read.

You should know that your code doesn't work very well. Besides the compile errors, it warns the user that they typed in the wrong letter before it checks to see if the letter is incorrect. I would use a loop like this (instead of the entire if block):
Code:
while ((response != 'Y') && (response != 'N'))
{
    cout<<"\nWrong Again---Try Again :";
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cin>>response;
    response = toupper(response);  
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top