RSS Forums RSS
Please support our C++ advertiser: Programming Forums
Views: 1835 | Replies: 17
Reply
Join Date: Dec 2004
Location: Allentown, PA
Posts: 60
Reputation: murschech is an unknown quantity at this point 
Rep Power: 4
Solved Threads: 1
murschech murschech is offline Offline
Junior Poster in Training

It's cinfull!

  #1  
Jan 1st, 2007
In using "cin" for getting input I have about a 99% success rate. In the remaining
1% of cases the program does not pause for input. What causes this and how does one fix it?

In ancient times when we programmed in C rather than C++ the same problem occurred
occasionally if "getc" or "getchar" was used for input. You could solve the problem by
putting the line "flushall()" before the input statement but that doesn't seem to
work with cin.

I ought to give an example but the only ones I have are in longish programs that I
wouldn't ask anyone to read.
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Aug 2005
Location: near St Louis, Missouri, USA
Posts: 11,628
Reputation: Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of 
Rep Power: 40
Solved Threads: 984
Moderator
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Most Valuable Poster

Re: It's cinfull!

  #2  
Jan 1st, 2007
same problem as in old days. when you enter a number and press <Enter> cin does not remove the "\n" from the keyboard -- you have to do that
int x;
cin >> x;
cin.ignore(); // remove '\n' key
<<Freelance Programmer>> << Hobby Site>>
Signature links for sale. PM me for details
Reply With Quote  
Join Date: Dec 2006
Posts: 209
Reputation: Ravalon is on a distinguished road 
Rep Power: 2
Solved Threads: 15
Ravalon's Avatar
Ravalon Ravalon is offline Offline
Posting Whiz in Training

Re: It's cinfull!

  #3  
Jan 2nd, 2007
Originally Posted by murschech View Post
In using "cin" for getting input I have about a 99% success rate. In the remaining 1% of cases the program does not pause for input. What causes this and how does one fix it?
You are probably mixing formatted and unformatted input. Formatted input treats whitespace differently than unformatted input, and if a formatted operation leaves '\n' in the stream, the unformatted operation will fail to do what you want depending on your program's logic. You fix it either by flushing the input stream at the right time or by not mixing formatted and unformatted input on the same stream.
Originally Posted by murschech View Post
In ancient times when we programmed in C rather than C++ the same problem occurred occasionally if "getc" or "getchar" was used for input. You could solve the problem by putting the line "flushall()" before the input statement but that doesn't seem to work with cin.
flushall() is not a standard function so you cannot expect it to work. You use cin.ignore() in C++.
#include <iostream>
#include <limits>

int main()
{
  using namespace std;

  // Create the problem by leaving a '\n' in the stream
  char letter = 0;

  cout << "Please type one letter: ";
  cin.get( letter );
  cout << "The next character is: " << (int)cin.get() << '\n';

  // Create the same problem and fix it with cin.ignore()
  cout << "Please type one letter: ";
  cin.get( letter );

  // Ignore the maximum value of the streamsize type or until '\n' is ignored
  cin.ignore( numeric_limits<streamsize>::max(), '\n' );

  // Now the cin.get() call will block because the stream is empty
  cout << "The next character is: " << (int)cin.get() << '\n';

  return 0;
}
The best fix is to avoid the problem completely by not mixing formatted and unformatted input. You always use unformatted input and then include logic to do the formatting. With C we did it using fgets and sscanf or something like that. With C++ you do it with getline and stringstream or something comparable.
#include <iostream>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <string>

namespace Raye {
  using namespace std;

  template <class T, class U>
  T CType( U src )
  {
    stringstream ss;
    T dst;

    if ( !( ss << src ) )
      throw runtime_error( "CType: stringize error" );
    
    if ( !( ss >> dst ) )
      throw runtime_error( "CType: invalid conversion" );

    return dst;
  }

  template <class T>
  T GetType( istream& is )
  {
    string s;

    if ( !getline( is, s ) )
      throw runtime_error( "GetInt: input failure" );

    return CType<T>( s );
  }
}

int main()
{
  using namespace std;

  int age;
  string name;

  // Create the problem as an example
  cout << "Please type your age: ";
  cin >> age;
  cout << "Please type your name: ";
  getline( cin, name );
  cout << name << " is " << age << " years old\n";

  // Clean up the stream for an accurate test
  cin.ignore( numeric_limits<streamsize>::max(), '\n' );

  // Eliminate the problem with GetType
  cout << "Please type your age: ";
  age = Raye::GetType<int>( cin );
  cout << "Please type your name: ";
  getline( cin, name );
  cout << name << " is " << age << " years old\n";

  return 0;
}
It is more work at first but the result is more robust.
It's hard to be humble when you're as gifted as I am at pretending to be an expert.
Reply With Quote  
Join Date: Jun 2006
Location: India
Posts: 7,054
Reputation: ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold 
Rep Power: 25
Solved Threads: 372
Moderator
Featured Poster
~s.o.s~'s Avatar
~s.o.s~ ~s.o.s~ is offline Offline
Lazy, Useless & Apathetic

Re: It's cinfull!

  #4  
Jan 2nd, 2007
Originally Posted by Ravalon View Post
flushall() is not a standard function so you cannot expect it to work. You use cin.ignore() in C++.
#include <iostream>
#include <limits>

int main()
{
  using namespace std;

  char letter = 0;
  cout << "Please type one letter: ";
  cin.get( letter );
  cout << "The next character is: " << (int)cin.get() << '\n';

  cout << "Please type one letter: ";
  cin.get( letter );

  cin.ignore( numeric_limits<streamsize>::max(), '\n' );

   cout << "The next character is: " << (int)cin.get() << '\n';

  return 0;
}

Though it would be really better if cin.clear( ) was placed before the call to cin.ignore( ) to deal with corrupted input stream along with the stray characters or junk in it. (eg. user enters a float in place of character).
Last edited by ~s.o.s~ : Jan 2nd, 2007 at 2:47 pm.
I don't accept change. I don't deserve to live.

Happiness corrupts people.

Failing to value the lives of others cheapens your own.
Reply With Quote  
Join Date: May 2006
Posts: 2,803
Reputation: WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold 
Rep Power: 16
Solved Threads: 236
Moderator
WaltP's Avatar
WaltP WaltP is offline Offline
Posting Maven

Re: It's cinfull!

  #5  
Jan 2nd, 2007
Keep in mind, cin is the C++ version of C's scanf() and must be used appropriately. IMAO that means -- don't!
Last edited by Ancient Dragon : Jan 2nd, 2007 at 3:10 pm.
Got a cough? Go home tonight and eat a whole box of Ex-Lax. Tomorrow, you'll be afraid to cough.
-- Pearl Williams
Reply With Quote  
Join Date: Jun 2006
Location: India
Posts: 7,054
Reputation: ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold ~s.o.s~ is a splendid one to behold 
Rep Power: 25
Solved Threads: 372
Moderator
Featured Poster
~s.o.s~'s Avatar
~s.o.s~ ~s.o.s~ is offline Offline
Lazy, Useless & Apathetic

Re: It's cinfull!

  #6  
Jan 2nd, 2007
Yes true, but if already used, why not make it a bit more er... robust...
I don't accept change. I don't deserve to live.

Happiness corrupts people.

Failing to value the lives of others cheapens your own.
Reply With Quote  
Join Date: Aug 2005
Location: near St Louis, Missouri, USA
Posts: 11,628
Reputation: Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of Ancient Dragon has much to be proud of 
Rep Power: 40
Solved Threads: 984
Moderator
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Most Valuable Poster

Re: It's cinfull!

  #7  
Jan 2nd, 2007
Originally Posted by WaltP View Post
Keep in mind, cin is the C++ version of C's scanf() and must be used appropriately. IMAO that means -- don't!


Don't you mean >> operator is like c's scanf() ? cin by itself is similar to c's stdin file pointer.
<<Freelance Programmer>> << Hobby Site>>
Signature links for sale. PM me for details
Reply With Quote  
Join Date: Dec 2006
Posts: 209
Reputation: Ravalon is on a distinguished road 
Rep Power: 2
Solved Threads: 15
Ravalon's Avatar
Ravalon Ravalon is offline Offline
Posting Whiz in Training

Re: It's cinfull!

  #8  
Jan 2nd, 2007
Originally Posted by ~s.o.s~ View Post
Though it would be really better if cin.clear( ) was placed before the call to cin.ignore( ) to deal with corrupted input stream along with the stray characters or junk in it. (eg. user enters a float in place of character).

Well, in real code I would check the error state of cin and deal with legitimate problems long before trying to do cin.ignore(). But real code is harder to read and has lots of extras that hide the point I'm trying to make.
Originally Posted by WaltP View Post
Keep in mind, cin is the C++ version of C's scanf() and must be used appropriately. IMAO that means -- don't!

Not to be nitpicky, but cin is the C++ version of C's stdin. The overloaded >> operator is the C++ version of scanf.
It's hard to be humble when you're as gifted as I am at pretending to be an expert.
Reply With Quote  
Join Date: May 2006
Posts: 2,803
Reputation: WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold WaltP is a splendid one to behold 
Rep Power: 16
Solved Threads: 236
Moderator
WaltP's Avatar
WaltP WaltP is offline Offline
Posting Maven

Re: It's cinfull!

  #9  
Jan 2nd, 2007
Originally Posted by Ravalon View Post
Not to be nitpicky, but cin is the C++ version of C's stdin. The overloaded >> operator is the C++ version of scanf.
So don't be nitpicky :p

Yes, you guys are right. So I change my statement:

Keep in mind, cin << is the C++ version of C's scanf() and must be used appropriately. IMAO that means -- don't!
Got a cough? Go home tonight and eat a whole box of Ex-Lax. Tomorrow, you'll be afraid to cough.
-- Pearl Williams
Reply With Quote  
Join Date: Dec 2006
Posts: 209
Reputation: Ravalon is on a distinguished road 
Rep Power: 2
Solved Threads: 15
Ravalon's Avatar
Ravalon Ravalon is offline Offline
Posting Whiz in Training

Re: It's cinfull!

  #10  
Jan 2nd, 2007
Originally Posted by WaltP View Post
So don't be nitpicky :p
But then I couldn't be nitpicky. Isn't nitpicking supposed to be one of life's true joys or something?
Originally Posted by WaltP View Post
Keep in mind, cin << is the C++ version of C's scanf() and must be used appropriately. IMAO that means -- don't!

cin >>, you mean.
It's hard to be humble when you're as gifted as I am at pretending to be an expert.
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes
Forums | Blogs | Tutorials | Code Snippets | Whitepapers | RSS Feeds | Advertising
All times are GMT -4. The time now is 5:30 pm.
Newsletter Archive - Sitemap - Privacy Statement - Acceptable Use Policy - Contact Us
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC