2011-04-26 91 views
0

在下面的代码中,我遇到了cin问题。第一个cin表现良好,但第二个cin完全没有收到任何输入。我试过cin.clear()清除输入流,但它没有帮助。从我所了解的是cin问题的规范。C++用cin输入问题

#include <iostream> 
#include <string> 
#include "StudentGradeInfo.h" 

using namespace std; 

const int MAX_NUM_GRADES=10; 
const int MAX_NUM_STUDENTS=50; 
const int STUD_ID_LENGTH=12; 

int main(){ 

    char choice=' '; //First user choice 
    char choice_2=' '; //second user choice 
    string newStudentMajor; //User inputted student major 
    string studLastName; //User inputted last name 
    int newStudentID; //User inputted student ID 
    int studGrade; //User inputted student grade 
    int studentCounter=0; //variable to count number of students 

    //Allocating dynamic memory for MAX_NUM_STUDENTS student objects 
    StudentGradeInfo *students=new StudentGradeInfo[MAX_NUM_STUDENTS]; 

    cout<<"Welcome to GradeBook, this program stores students" 
    <<" grades by last name. To ADD a student press the 'A'" 
    <<" key. To LIST all students, press the 'L' key. To " 
    <<" QUIT, press the 'Q' key."<<endl<<endl; 

    cin>>choice; 

    choice=toupper(choice); 

    while(choice!='Q') //While user does not decide to quit 
    { 
     if(choice=='A'&& studentCounter<MAX_NUM_STUDENTS){ //If user chooses to ADD 
      cout<<"\nTo add a student, please enter their last name" 
      <<" followed by a space and a non-negative grade" 
      <<" Ex. Arthur 96"<<endl<<endl; 
      cin>>studLastName>>studGrade; //this cin works fine and using the 
                //debugger I find that they contain 
                //the correct values 
      cout<<cin.peek(); //Looking for chars left in input stream 
      const char *charLastName=studLastName.c_str(); 
      int lastNameLength=studLastName.length(); 

      //Assign name to student object 
      students[studentCounter].SetStudentName(charLastName, lastNameLength); 
      //Set Test Grade for student object 
      students[studentCounter].SetStudentTestGrade(studGrade); 

      cout<<"\nPlease enter the "<<STUD_ID_LENGTH<<"-digit Student ID followed by " 
       <<"a space, then enter the student's major (Ex. 123456789012 Math)"<<endl; 
      cin.clear(); 
      cin>>newStudentID>>newStudentMajor; //User input 
      cout<<newStudentID<<" "<<newStudentMajor; 
      cout<<cin.peek(); //Checking for chars left in input stream 
      //Adding ID and Major to students object. 
      students[studentCounter].SetStudentID(newStudentID); 
      students[studentCounter].SetStudentMajor(newStudentMajor); 
      cout<<students[studentCounter].GetStudentID(); 
      cout<<"\nWould you like to enter more grades for this " 
      <<"student? If yes, please enter 'Y', if no, " 
      <<"enter 'N'"<<endl; 

      cin>>choice_2; 
      choice_2=toupper(choice_2); //Upper-case conversion 

      while(choice_2!='N'){ 
       if(choice_2=='Y'){ 
        cout<<"\nPlease enter a grade followed by pressing " 
        <<"enter.\n"; 

        for(int i=0;i<MAX_NUM_GRADES;i++){ //Inputting grades for individual 
         cin>>studGrade;   //student 
         if(studGrade==-1) //Condition for premature loop exit 
          break; 
         students[studentCounter].SetStudentTestGrade(studGrade); //Add Grade 
         cout<<"\nWould you like to add another grade? " 
         <<"If so, enter the next grade. Otherwise" 
         <<" enter -1 to return to the menu"<<endl; 
        } 
        cout<<"This student currently has the maximum number of grades. \n"; 
        break; 
       }//If answer yes is chosen 
       else if(choice_2!='N'&& choice_2!='Y'){ //If wrong character is input 
        cout<<"\nPlease enter either 'Y' or 'N'"<<endl; 
        cin>>choice_2; 
        choice_2=toupper(choice_2); //Upper-case conversion 
       } 
      }//While choice_2!='N' 
      students[studentCounter].SortStudentID(students); 
      studentCounter++; //Incrementing studentCounter after all possible changes have 
           //been made to that student 
     } 

     else if(choice=='L'){ //If user decides to list 
      cout<<"GRADEBOOK \n------------------------------\n"; 

      for(int i=0; i<studentCounter; i++){ //Such a better solution than last gradebook 
       cout<<"\nentering list loop \n"; 
       cout<<students[i]; //Overloaded insertion operator, outputs all student information 

      } 
     } 

     else if(choice!='Q') //If user inputs invalid character 
      cout<<"Your letter is invalid, please enter another letter"<<endl<<endl; 

     cout<<"\nTo ADD a student press the 'A' key. To LIST all students, press the 'L' key. " 
     <<" To QUIT, press the 'Q' key."<<endl<<endl;  

     cin>>choice; 
     choice=toupper(choice); //Upper-case conversion 
    } 
} 

StudentInfo.cpp

#include <iostream> 
#include <string> 
#include "StudentInfo.h" 

using namespace std; 

const int STUDENT_ID_LENGTH=12; 

    //default constructor 
StudentInfo::StudentInfo() 
{ 
} 
//Parameterized constructor 
StudentInfo::StudentInfo(string newStudentName, int newStudentID, string newStudentMajor) 
{ 
    int nameLength=newStudentName.length(); 
    char *nameArray=new char[nameLength]; 

    SetStudentName(nameArray, nameLength); 
    SetStudentID(newStudentID); 
    SetStudentMajor(newStudentMajor); 
} 

StudentInfo::~StudentInfo() //Destructor 
{ 
    delete[] studentName; //deallocating dynamic memory 
} 

//Member functions for initializing and displaying private data 
//pre: array of characters and a positive int for nameLength 
//post: studentName contains name of new student 
void StudentInfo::SetStudentName(const char newStudentName[], int lastNameLength) 
{ 
    char *studentName=new char[lastNameLength]; 

    for(int i=0; i<lastNameLength; i++){ 
     studentName[i]=newStudentName[i]; 
    } 
} 

//post: Returns name of student 
string StudentInfo::GetStudentName() const 
{ 
    return studentName; 
} 

//pre: positive integer input 
//post: studentID contains newStudentID or msg is displayed that ID is invalid 
void StudentInfo::SetStudentID(int newStudentID) 
{ 
    double new_ID; 
    int divisionsCount=0; 
    new_ID=newStudentID; 
    while(new_ID>1){ 
     new_ID=new_ID/10; 
     divisionsCount++; 
    } 

    if(divisionsCount!=STUDENT_ID_LENGTH){ 
     cout<<"ID is not "<<STUDENT_ID_LENGTH<<" characters long\n"; 
     return; 
    } 
    studentID=newStudentID; 
} 
//pre: valid integer for studentID 
//post: returns integer to caller 
int StudentInfo::GetStudentID() const 
{ 
    return studentID; 
} 

//pre: String type of student Major and newStudentMajor 
//post: studentMajor contains newStudentMajor string 
void StudentInfo::SetStudentMajor(string newStudentMajor) 
{ 
    studentMajor=newStudentMajor; 
} 

//post: returns string studentMajor 
string StudentInfo::GetStudentMajor() const 
{ 
    return studentMajor; 

StudentGradeInfo.cpp

#include <string> //including string data type 
#include <iostream> 
#include "StudentGradeInfo.h" 

using namespace std; 

StudentGradeInfo::StudentGradeInfo():StudentInfo() 
{ 
    //StudentInfo::StudentInfo(); 
    gradeCounter=0; 
} 

//Parameterized Constructor 
StudentGradeInfo::StudentGradeInfo(string &newStudentName, int &newStudentID, 
       string &newStudentMajor, int newTestGrade, double newtestAverage, int newGradeCounter): 
       StudentInfo(newStudentName, newStudentID, newStudentMajor) 
{ 
    gradeCounter=0; 
    SetStudentTestGrade(newTestGrade); 
} 

//pre: positive integer input 
//post: testGrade contains newTestGrade or msg is displayed that the score is invalid or contains max # of grades 
void StudentGradeInfo::SetStudentTestGrade(int newTestGrade) 
{ 
/* if(gradeCounter>MAX_NUM_GRADES){ //If the maximum number of grades has been reached 
     cout<<"\nThis student currently has the maximum number of grades."; //Inform user 
     return;       //Leave function and not assign input grade 
    }*/ 
    testGrade[gradeCounter]=(newTestGrade > 0 && newTestGrade<=100) ? newTestGrade : -1; //Grade assignment 
    if(testGrade[gradeCounter]!=-1)              //and validity testing 
     gradeCounter++; //Increment number of grades this student has 
    else 
     cout<<endl<<testGrade[gradeCounter]<<" is not a valid score.\n"; //Inform user which score was invalid 
} 

//pre: positive integer 
//post: returns testGrade found in that array 
int StudentGradeInfo::GetStudentTestGrade(int gradeNum) const 
{ 
    if(gradeNum>=0 && gradeNum<=MAX_NUM_GRADES) //If gradeNum is a valid grade and not stepping off of array 
     return testGrade[gradeNum]; 
    else 
     return 0; 
} 

//post: testAverage is calculated 
void StudentGradeInfo::SetTestAverage() 
{ 
    int num_Sum; 
    for(int i=0;i<gradeCounter;i++) 
     num_Sum+=testGrade[i]; //summing total grades 
    testAverage=(num_Sum/(gradeCounter+1)); //Calculating average 
} 

//post: returns calculated testAverage double 
double StudentGradeInfo::GetTestAverage() 
{ 
    SetTestAverage(); 
    return testAverage; 
} 

//pre: initialized StudentGradeInfo object array 
//post: Students are sorted by studentID 
void StudentGradeInfo::SortStudentID(StudentGradeInfo newStudent[]) 
{ 
    int tempValue; 

    while(IDSorted(newStudent)!=true){ //If students are not sorted 
     for(int i=0; i<(gradeCounter-1); i++){ 
      //Determining if these two students need switched 
      if(newStudent[i].GetStudentID()<=newStudent[i+1].GetStudentID()) 
       continue; //If they don't need switched, continue 
      else{ //Otherwise switch the two students 
       tempValue=newStudent[i+1].GetStudentID(); 
       newStudent[i+1].SetStudentID(newStudent[i].GetStudentID()); 
       newStudent[i].SetStudentID(tempValue); 
      } 
     } 
    } 
} 

//pre: initialized StudentGradeInfo object array 
//post: returns true if newStudent array has been sorted by studentID, false otherwise 
bool StudentGradeInfo::IDSorted(StudentGradeInfo newStudent[]) 
{ 
    for(int i=0; i<(gradeCounter-1);i++){ //Determining if array is sorted from smallest to largest 
     if(newStudent[i].GetStudentID()<=newStudent[i+1].GetStudentID()) 
      continue; 
     else 
      return false; 
    } 
    return true; 
} 

//Overloaded insertion operator to output entire students information 
ostream &operator<<(ostream &output, StudentGradeInfo &newStudent) 
{ 
    output<<"This is the student major: "<<newStudent.GetStudentMajor(); 

    output<<"__________________________________\n" 
      <<"Name: "<<newStudent.GetStudentName()<<"\nID: "<<newStudent.GetStudentID() //outputs studentID and name 
      <<"\nMajor: "<<newStudent.GetStudentMajor()<<"\nGrades: ";  //outputs studentMajor 
    for(int i=0;i<newStudent.gradeCounter;i++) 
     output<<newStudent.testGrade[i]<<" "; //outputs studentGrade's 
    output<<"Grade Average: "<<newStudent.GetTestAverage(); 
    return output; 
} 

bool operator==(StudentGradeInfo &newStudent_One, StudentGradeInfo &newStudent_Two) 
{ 
    if(newStudent_One==newStudent_Two) //testing for equality 
     return true; 
    else 
     return false; 
} 
    } 

在此先感谢

+0

对不起,我现在没有时间去调试这个,但这是我的猜测:学生ID不适合'int'。您是否可以将STUD_ID_LENGTH降低到6并重新运行实验? – 2011-04-26 23:00:37

+0

它工作,在我的任务(是的,它是作业),它需要是12位数字。我怎样才能做到这一点? – ChadM 2011-04-26 23:03:22

+0

将学生ID存储在“std :: string”而不是“int”中。 – 2011-04-26 23:04:26

回答

2

你的学生证是12位长。没有12位十进制值适合32位整数。尝试将其存储在字符串中。