CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Apr 2007
    Posts
    14

    Having issues with cin.getline and cin

    In our final assignment for the year, we were given an assignment to create an array to structs that held information pertaining to students in a class. I have the program done essentially, but I'm getting a really annoying bug where with every loop past the first one, the program is "skipping over" inputting the students name for the 2nd, 3rd, 4th, etc... loops.

    I believe I've isolated the problem to being something with cin.getline, and something about needing to clear the buffer after every loop. I can't seem to figure out how to clear the buffer.

    Student.h
    Code:
    // Global constants
    const int STUDENT_NAME = 41;	// Max number of characters for a students name
    const int STUDENT_MAJOR = 41;	// Max number of characters for a students major
    const int STUDENT_YEAR = 21;	// Max number of characters for a students year
    const int STUDENT_ID = 5;
    
    // Declaration of our Student Structure
    struct Student
    {
    	char name[STUDENT_NAME];	// Stores full name of student
    	char major[STUDENT_MAJOR];	// Stores major of student
    	char year[STUDENT_YEAR];	// Stores year of student (Freshman, Sophomore, Junior, Senior)
    	int studentID;				// Unique number to identify each student
    	float GPA;					// Students Grade Point Average
    };
    
    // Declaration of our class
    class myRoster
    {
    	public:
    		void FillRoster (Student CourseRoster[], int classSize);
    		float AverageGPA (Student CourseRoster[], int classSize);
    		void OutputRoster (Student CourseRoster[], int classSize, char *pClassName, char *pClassNumber);
    	private:
    		struct myStruct
    		{
    			int a;
    			int b;
    			float c;
    		};
    
    
    		
    
    
    };
    Implementation.cpp
    Code:
    #include <iostream>
    #include <iomanip>
    
    #include "Student.h"
    
    using namespace std;
    
    
    // FillRoster will take each student in the class (in our case, 6) and
    // populate their name, their major, their student ID, and their GPA.
    void myRoster::FillRoster (Student CourseRoster[], int classSize)
    {
    	for (int i = 0; i < classSize; i++)
    	{
    		// Get Students Name
    		cout << endl << "Enter the students name. > ";
    		cin.getline(CourseRoster[i].name, STUDENT_NAME);
    		cin.ignore(cin.rdbuf()->in_avail(), '40');
    		
    		// Get Students Major
    		cout << endl << "Enter the students major. > ";
    		cin.getline(CourseRoster[i].major, STUDENT_MAJOR);
    		cin.ignore(cin.rdbuf()->in_avail(), '40');
    		
    		do
    		{
    			// Get Students Student ID. 
    			CourseRoster[i].studentID = 10000;
    			cout << endl << "Enter the students ID number (Between 10000 and 99999). > ";
    			cin >> CourseRoster[i].studentID;
    		}
    		while (CourseRoster[i].studentID < 10000 || CourseRoster[i].studentID > 99999);
    		
    		do
    		{
    			// Get Student GPA
    			cout << endl << "Enter the students GPA. > ";
    			cin >> CourseRoster[i].GPA;
    		}
    		while (CourseRoster[i].GPA < 0.0 || CourseRoster[i].GPA > 4.0);		
    	}
    	return;
    }
    
    
    float myRoster::AverageGPA (Student CourseRoster[], int classSize)
    {
    	// Declare variable to hold the average GPA
    	float avgGPA = 0.0;
    
    	for (int j = 0; j < classSize; j++)
    	{
    		avgGPA = avgGPA + CourseRoster[j].GPA;
    	}
    
    	avgGPA = avgGPA / classSize;
    
    	return avgGPA;
    }
    
    
    void myRoster::OutputRoster (Student CourseRoster[], int classSize, char *pClassName, char *pClassNumber)
    {
    	// Print out all the relevant information of the class and its students
    	cout << endl << endl << "Roster for " << pClassName << ", Course ID " << pClassNumber << " is as follows: ";
    	cout << endl << endl;
    	cout << "NAME \t\t STUDENT ID \t\t ACADEMIC MAJOR \t GPA" << endl << endl;
    	for (int k = 0; k < classSize; k++)
    	{
    		cout << CourseRoster[k].name << " \t\t " << CourseRoster[k].studentID << " \t\t\t "
    			<< CourseRoster[k].major << " \t\t\t " << CourseRoster[k].GPA << endl;
    	}
    
    
    	return;
    }
    Main.cpp
    Code:
    #include <iostream>
    #include <iomanip>
    
    #include "Student.h"
    
    using namespace std;
    
    // Constants used througout the program
    const int CLASS_SIZE = 2;	// Class/Roster size
    const int CLASS_TITLE = 41;	// Max size of a class name.  Extra space for the NULL character.
    const int CLASS_NUMBER = 9; // Max size of the class number name.  Extra space for the NULL character.
    
    int main()
    {
    	// Create my strut object
    	Student CourseRoster[CLASS_SIZE];
    
    	// Create my class object 
    	myRoster roster;
    
    	// Create variables needed by the program.  className holds the name of the class,
    	// classNumber holds the class abbreviation (CS115), avgGPA holds the average GPA
    	// of the students in the class.  pAvgGPA is a pointer to avgGPA.
    	char className[CLASS_TITLE];
    	char classNumber[CLASS_NUMBER];
    
    	char *pClassName = &className[0];
    	char *pClassNumber = &classNumber[0];
    	float *pAvgGPA = NULL;
    		
    	// Get the course name and course number from the user.  The cin.ignore lines 
    	// ensure that we only take up to the maximum number of characters allowed by that 
    	// field so that we don't accidentally try to create a course name with 60 
    	// characters or a course number with 15 characters.
    	cout << "Enter the name of the course. > ";
    	cin.getline(className, CLASS_TITLE);
    	cin.ignore(cin.rdbuf()->in_avail(), '40');
    
    	cout << endl << "Enter the course number. > ";
    	cin.getline(classNumber, CLASS_NUMBER);
    	cin.ignore(cin.rdbuf()->in_avail(), '8');
    
    	// Call the FillRoster Function
    	roster.FillRoster(CourseRoster, CLASS_SIZE);
    
    	// Calculate the Average GPA of the students
    	cout << "The average GPA for the students in " << className << "is " 
    		<< roster.AverageGPA(CourseRoster, CLASS_SIZE);
    
    	// Output the class information
    	roster.OutputRoster(CourseRoster, CLASS_SIZE, pClassName, pClassNumber);
    
    
    	myRoster.myStruct.a = 1;
    
    	system("pause");
    	return 0;
    }
    Can anyone assist in fixing this annoying output issue?

  2. #2
    Join Date
    Oct 2008
    Posts
    45

    Re: Having issues with cin.getline and cin

    I used to have lots of problem when using cin.getline, now Im not an expert with this kind of stuff but what we used to do to solve them is put a:
    Code:
    char enter[1];
    cin.getline(enter,1);
    after calls to cin>> (the operator >>()) cause as it seems cin>> leaves an enter when it reads from the stream so when cin.getline comes to read after cin>> it finds the enter and directly exit with nothing read, now putting the previous code after cin>> removes this enter and you can read whats after it. I can be a bit off about the details but I know this used (and still) to solve my problems with cin.getline, hope this was useful

    btw what is:
    Code:
    cin.ignore(cin.rdbuf()->in_avail(), '40');

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured