Solved

CIN isn't stopping to get input

Posted on 2006-06-12
7
336 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
Industry Leaders: 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

Technology Partners: 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!

Question has a verified solution.

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

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 the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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.

726 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