Thread: Confused about cin.get(); and classes.

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    12

    Confused about cin.get(); and classes.

    Thanks in advance for reading. I'm new to these boards so I hope it's alright that my first post is a question.

    Generally I use cin.get(); to pause a console application right before it ends, so that I can see what I've done without using cmd.exe to exec my program.

    Today though, I tried my hand at classes, and for some reason if I don't cin.ignore(); after every input instance in the program, the program runs and then quits, 'ignoring' my cin.get(); at the end.

    The program is posted below with the cin.ignore();'s commented out. I was just wondering if anyone can tell me WHY I need cin.ignore(); just because a class exists somewhere in the program? Is there a better way to do it?

    Code:
    #include <iostream>
    using namespace std;
    
    class DayOfYear
    {
    public:
    	void output();
    	int month;
    	int day;
    };
    
    int main(void)
    {
    	DayOfYear today, birthday;
    
    	cout << "Today's Date:\n\n"
    		<< "Please enter the current month as a number: ";
    	cin >> today.month;
    	// cin.ignore();
    	
    	cout << "And the day.  What day is it? ";
    	cin >> today.day; 
    	// cin.ignore();
    
    	cout << "Birthdate:\n\n"
    		<< "Enter your birthmonth as a number: ";
    	cin >> birthday.month; 
    	// cin.ignore();
    
    	cout << "And last, enter the day you were born: ";
    	cin >> birthday.day; 
    	// cin.ignore();
    
    	cout << "Today's date is ";
    	today.output();
    	cout << "Your birthday is ";
    	birthday.output();
    
    	if (today.month == birthday.month && today.day == birthday.day)
    		cout << "Happy Birthday!\n";
    	else cout << "Happy Unbirthday!\n";
    
    	cin.get();
    	return 0;
    }
    
    void DayOfYear::output()
    {
    	cout << "month = " << month << ", day = " << day << endl;
    }
    PS: I'm using Visual C++ .net 2003 Standard, creating a new blank and empty win32 console application and right clicking "source files" and choosing "add>add new item" which is a .cpp file.

    EDIT: I just built it with the ignores commented out, but at the end a cin.ignore(); after the final cin.get(); and it has the same effect (the program pauses). So now I'm more confused than ever.
    Last edited by RaccoonKing; 07-17-2005 at 09:00 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The program is posted below with the cin.ignore();'s commented out. I was just wondering if anyone can tell me WHY I need cin.ignore(); just because a class exists somewhere in the program? Is there a better way to do it?
    It has little to do with your classes. Rather after entering input, there is an additional newline at the end. cin >> var reads up to whitespace, so it leaves the newline in the buffer. You need to ignore() that newline.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >tell me WHY I need cin.ignore(); just because a class exists somewhere in the program?
    It has nothing to do with the class. Formatted input and unformatted input don't play well together, so unless you use cin's >> operator exclusively, you'll have issues where there's a newline character left in the stream. cin.get() doesn't do a blocking read if it immediately finds a newline.

    This exhibits the same problem:
    Code:
    #include <iostream>
    
    int main()
    {
      int x;
    
      std::cout<<"Enter a number: ";
      std::cin>> x;
      std::cout<<"Press enter to continue";
      std::cin.get();
      std::cout<<"You pressed enter\n";
    }
    cin's >> operator stops reading at the first whitespace, but doesn't actually extract the whitespace from the stream. So if you type 123<enter>, the <enter> stays in the stream for cin.get() to read immediately and terminate on. So the program doesn't wait for more input from you.
    My best code is written with the delete key.

  4. #4
    Registered User
    Join Date
    Jul 2005
    Posts
    12
    Ok, so because cin >> var ends at the first whitespace (which would be the newline I guess?), but does NOT actually use the newline that you give it by pressing [Enter], the newline stays in the buffer and cin.get(); somehow evaluates to "skip me".

    Any idea why, when I do this:

    Code:
    cin.get();
    cin.ignore();
    return 0;
    }
    at the end, the pause comes back (i.e. the window stays open when done 'till I hit [Enter])? That was the most confusing part to me of this whole thing.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >somehow evaluates to "skip me".
    You could say it like that, but in reality it doesn't skip anything, it does exactly what you told it to do. cin.get() expects a character. If the stream is not empty, it reads whatever the first character is there and terminates successfully.

    >at the end, the pause comes back
    cin.ignore() is an unformatted input function too. Like cin.get(), if the stream is empty when you call it, it waits until there are characters to read.
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Jul 2005
    Posts
    12
    Ok, so by putting it at the end cin.get(); eats the buffer and cin.ignore(); is what actually does the waiting.

    Thanks very much to all of you.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >so by putting it at the end cin.get(); eats the buffer and cin.ignore(); is what actually does the waiting.
    Yes, though if the stream contains more than one character, it won't work no matter which way you order the two. That's why cin.ignore() is usually first, but the two argument version is used instead to actually clear the stream of all characters, then do a blocking read with cin.get():
    Code:
    #include <limits>
    
    //...
    
    std::cin.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
    std::cin.get();
    The zero argument version of ignore() only discards one character.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. switches and classes... so very very confused :( plz clarify
    By MegaManZZ in forum C++ Programming
    Replies: 15
    Last Post: 08-28-2008, 01:10 PM
  2. Confused about classes
    By augie0216 in forum C# Programming
    Replies: 1
    Last Post: 02-25-2006, 09:08 AM
  3. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  4. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  5. A little confused on classes
    By Munkey01 in forum C++ Programming
    Replies: 18
    Last Post: 02-04-2003, 05:59 AM