When this program runs, I can enter in the name the first time through the while loop (using "cin.getline). When I go through the second time, it skips the name and asks to enter the ss#.

The first time through, everything works fine.

#include <iomanip>
#include <iostream>
#include <fstream>
using namespace std;

 struct student_rec 
  {
     char name[30];
     char ss[9];
     int grade_3cr[4];
     int grade_1cr[1];
  };
   
   void initializeStudent (student_rec &any_student)
    {
       any_student.name[30] = '                             '; 
       any_student.ss[9] = '        ';
       any_student.grade_3cr[0] = 0;
       any_student.grade_3cr[1] = 0;
       any_student.grade_3cr[2] = 0;
       any_student.grade_3cr[3] = 0;
       any_student.grade_1cr[0] = 0;
    }                          
    
  void processStudent (student_rec &your_student, const int& CREDIT_3, const int& CREDIT_1)
    {
         cout.setf(ios::fixed);
         int i = 0,
             tot_credits = 0,
             tot_grade = 0;
         float gpa;
         
         cout<<setw(15)<<your_student.name
             <<setw(15)<<your_student.ss
             <<"     ";
         for (i=0;i<=3;i++)
           {
              cout<<setw(3)<<your_student.grade_3cr[i]
                  <<" ";
            tot_grade = tot_grade + (your_student.grade_3cr[i] * CREDIT_3);
            tot_credits += CREDIT_3;
            }
         
         cout<<setw(8)<<your_student.grade_1cr[0]
             <<endl<<endl;
         tot_grade = tot_grade + (your_student.grade_1cr[0] * CREDIT_1);
         tot_credits += CREDIT_1;
         gpa = tot_grade / tot_credits;

         cout<<"Students total credits this senester is "
             <<tot_credits<<endl<<endl;
         cout<<"students overall gpa is "
             <<setprecision(2)<<gpa<<endl<<endl;
}
   
int main()
{
   /*--------------------------------------
    * Initialize variables 
    *------------------------------------*/
  int i,
      rec_cnt = 1;

  const int CREDIT_3 = 3;
  const int CREDIT_1 = 1;
  const int STUDENTS_IN_CLASS = 2;
      
  student_rec your_student;  
  student_rec first_student;  
  student_rec second_student;  
  initializeStudent(first_student);        
  initializeStudent(second_student);
  
  cout<<"\n\n     .......  Student Records ....... \n\n";              
  while (rec_cnt <= STUDENTS_IN_CLASS)
      { 
         initializeStudent(your_student);
         cout<<"          Enter in Name of Student: ";
         cin.getline(your_student.name, sizeof(your_student.name));
         cout<<"\n        Enter in Student SS#: ";
         cin>>your_student.ss;
         cout<<"\n        Enter in Students Four 3 Cedit Gades: ";
         for (i = 0;i<=3;i++)
            cin>>your_student.grade_3cr[i];
         cout<<"\n        Enter in Students Single 1 Credit Grades: ";
         i = 0; 
         cin>>your_student.grade_1cr[i];
  
         if (rec_cnt == 1)   
            first_student = your_student;
         else
            second_student = your_student;
         rec_cnt++;    
      }
        system ("CLS");
        cout<<"Student Name      Soc. Sec. No.    3 Credit Grades    1 Credit Grade\n"
            <<"---------------   --------------   ----------------   --------------\n"
            <<endl<<endl;
            
         initializeStudent(your_student);        
         your_student = first_student;
         processStudent (your_student, CREDIT_3, CREDIT_1);   
             
         initializeStudent(your_student);        
         your_student = second_student;  
         processStudent (your_student, CREDIT_3, CREDIT_1);   
       
 system("PAUSE");        
 return 0;      
}

As always, I appreciate your help:)

Bob

Recommended Answers

All 10 Replies

It's hardly a strange problem since everybody sees it when learning C or C++. getline reads characters until a newline character is encountered, but cin>> leaves newlines on the stream. So a cin>> followed by a getline will typically cause problems.

>As always, I appreciate your help
Apparently not enough to use code tags.

Narue,

the cin.getline is mentioned in two C++ books I have as a way to enter in a string (where you can't with just "cin".

Also, what do you mean by "code tags"?

Thanks,

>the cin.getline is mentioned in two C++ books I have as a way to enter in a string (where you can't with just "cin".
You can enter a string with cin's operator>>, just not one with whitespace by default. And that has no bearing on the problem at hand. You use cin.getline to read a string, then you use cin>> to read a number. That leaves a newline in the stream and the next call to cin.getline appears to be skipped because it immediately sees the termination character.

>Also, what do you mean by "code tags"?
Code tags. Use them when posting code.

Narue,

What would you use to enter text into an array (such as a name)?

Thanks,


Bob

>What would you use to enter text into an array (such as a name)?
cin.getline, of course. You're missing the point and focusing on your strings while the problem is here:

cin>>your_student.grade_1cr[i];

Add this, since you seem incapable of solving a problem after being told what it is:

cin>>your_student.grade_1cr[i];
cin.ignore(numeric_limits<streamsize>::max(), '\n');

And don't forget to include <limits>.

Another way to purge all those wobbly '\n' ...

// clear the stream, purge any \n
  while (cin.get() != '\n')
    ;

Goofy? Yes, these pitfalls make C++ one of the most difficult languages to learn. Kind of job security in the end.

>Another way to purge all those wobbly '\n' ...
That example is incompete, which is why cin.ignore is a superior alternative. It forces you to provide all of the requisite information whereas with the loop approach it's easy to miss a very important test for end-of-file. The correct loop would be:

while (std::cin.get(ch) && ch != '\n')
  ;

Or using the C-style alternative:

while ((ch = std::cin.get()) != EOF && ch != '\n')
  ;
void initializeStudent (student_rec &any_student)
    {
       any_student.name[30] = '                             '; 
       any_student.ss[9] = '        ';

You have to be kidding me.

I'm assuming (I'm hoping) this was your intention:

memset(any_student.name,0,sizeof(any_student.name));
..

I'm assuming this barbaric system("PAUSE") is a Windows thing, but because we all know that good C++ code is interoperable C++ code, make sure you run ispell when you compile on a *nix system (and naturally, remove system("PAUSE"), or wrap it in __WINDOWS__).

What the heck is a "senester"? ;)

The system("PAUSE") is a method of using the PC system commands.

This is what we do with each class assignment to see the displayu from the cout's

Thanks,

>Another way to purge all those wobbly '\n' ...
That example is incompete, which is why cin.ignore is a superior alternative. It forces you to provide all of the requisite information whereas with the loop approach it's easy to miss a very important test for end-of-file. The correct loop would be:

while (std::cin.get(ch) && ch != '\n')
  ;

Or using the C-style alternative:

while ((ch = std::cin.get()) != EOF && ch != '\n')
  ;

Thanks Narue, for pointing this out! None of us wants to be incompete! Actually, the word has a ring to it, like "incomplete incompetence".

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.