Solved

CIN isn't stopping to get input

Posted on 2006-06-12
7
322 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
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
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 technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

708 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now