Solved

CIN isn't stopping to get input

Posted on 2006-06-12
7
334 Views
Last Modified: 2007-12-19
Can someone tell me why the first time through this loop if I type a char the next time through it doesn't stop to ask me for a new input?

int askQuestion(string strQuestion){
      int intResponse;
      bool bValidResponse = false;
      while (bValidResponse == false){
            intResponse = 0;
            cout << strQuestion;
            cin >> intResponse;
            cin.get();
            cout << endl;
            try{
                  if (intResponse >= 1 && intResponse <= 9){
                        bValidResponse = true;
                  }
                  else{
                        throw InvalidInput();
                  }
            }
            catch(InvalidInput myInvalidInput){
                  cout << myInvalidInput.what() << endl << endl;
            }
      }
      return intResponse;
}
0
Comment
Question by:BofADev
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 16890896
Try to read the input as a full line of text and convert it to int later, e.g.:

#include <sstream>

int askQuestion(string strQuestion){
     int intResponse;
     bool bValidResponse = false;
     while (bValidResponse == false){
          intResponse = 0;
              string strLine;
              stringstream ss;
          cout << strQuestion;
              getline(cin,strLine);
              ss << strLine;
          ss >> intResponse;
          cout << endl;
          try{
               if (intResponse >= 1 && intResponse <= 9){
                    bValidResponse = true;
               }
               else{
                    throw InvalidInput();
               }
          }
          catch(InvalidInput myInvalidInput){
               cout << myInvalidInput.what() << endl << endl;
          }
     }
     return intResponse;
}
0
 

Author Comment

by:BofADev
ID: 16891311
Nope didn't work.
0
 
LVL 86

Expert Comment

by:jkr
ID: 16891402
Hm, are you using VC++ 6.0? If so, the following article http://support.microsoft.com/default.aspx?scid=kb;en-us;240015 ("The getline template function reads an extra character after encountering the delimiter") will fix that problem an IIRC your original one also.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 17

Expert Comment

by:rstaveley
ID: 16892170
If you type A<enter> and then read from standard input into an integer with...

     cin >> intResponse;

...the stream's fail bits are set, beacuse it chokes on 'A'. Both characters are left in the standard input stream. cin.get() doesn't remove the character from the input stream, because the stream's failure flag has been set. You'll need to call cin.clear() to clear the failure bit, if you want to extract characters thereafter.

jkr is right in pointing you towards line input and extracting tokens from the line.

0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 16895971
As you are looking for a single digit only you could change your func to that:

int askQuestion(string strQuestion)
{
     char c = '\0 ';
     cout << endl << strQuestion;
     while (c < '0' || c > '9')
     {
          cin >> c;
     }
     return (int)(c - '0');
}

The behavior isn't quite that you might expect cause you have to type Enter to get the input, but it will only stop if there is at least one digit in the input stream (and returns the first of them).

A better behavior you would get by that:

int askQuestion(string strQuestion)
{
     string s;
     while (s.length() != 1 || s[0] < '0' || s[0] > '9')
     {
         cout << endl << strQuestion;
         getline(cin, s);
     }
     return (int)(s[0] - '0');
}

If that doesn't work and you are on VC6 you may have to fix the bug jkr mentioned before succeeding.

Finally, there is a 'DOS' solution that might not work on a non-Windows platform:

#include <conio.h>

int askQuestion(string strQuestion)
{
     char c = '\0 ';
     while (c < '0' || c > '9')
     {
         cout << endl << strQuestion;
         c = getche();
     }
     return (int)(c - '0');
}

Regards, Alex




0
 
LVL 4

Accepted Solution

by:
havman56 earned 500 total points
ID: 16942493

dont mix formated input and unformatted input .


when u type
formated input :
***********
cin >> intResponse;
function gets executed :
basic_istream <charT ,traits >& operator >>( int & n );
conclusion:  no problem

unformatted input
*************
int_type get ();
this is unformatted input
c++ standard says , "it extracts single character if it is avaliable. else function sets setstate(failbit) . now stream is ios::failure state
so u need to clear ".

i feel u can do evrything in formatted input

otherwise use getche()











0
 
LVL 4

Expert Comment

by:havman56
ID: 16942501
c++ standrad statement for get()

int_type get ();
4 Effects: Behaves as an unformatted input function (as described in 27.6.1.3, paragraph 1). After constructing
a sentry object, extracts a character c , if one is available. Otherwise, the function calls setstate(failbit),
which may throw ios_base::failure (27.4.4.3),
5 Returns: c if available, otherwise traits::eof().
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question