// Programmer: Aaron Shbeeb // File: Grades2.cpp // Created: 07-30-03 // Updated: 08-01-03 // grade-file format: (first line contains no data) // ", ", , ,,hw#1,...,hw#m,,cl#1,...cl#n,,lb#1,...lb#r,,ts#1,...ts#p // TYPE // gradeinfo-file format: // #cghw#1,...,#cghw#5 // #hw, #cl, #lb, #ts //2 [0 | 1] //2 //2 //2 //2,3 , //3 , // ... //3 , // TYPE specifies the type of gradeinfo file to read // 1. only the first two lines are parsed // 2. up to the instructor name is parsed, no email address expected // 3. all info is parsed // Here, 0 means don't include statistics 1 means do include // statistics. // Also, year is in the typical format (4 digits) // quarter can be: 0, 1, 2, or 3, which represent Au, Wi, Sp, or Su respectively // usage: argv[0] grade-file gradeinfo-file output-file // output-file is an HTML file with 4 tables, 1 for each of the // different kinds of assignments (hw, cl, lb, ts) #include #include "CIS_Grades2/CIS_Grades2.h" #include "CIS_Course2/CIS_Course2.h" #include "Student/Student.h" //I think the original is //good enough here #include "String/String.h" #define DEBUG 0 //0 for no debug, 1 for debug //Utility Functions void Read_GradeInfo_File(ifstream& in, CIS_Course& Course, CIS_Grades& Grades); //alters Grades void Read_Grade_File(ifstream& in, CIS_Course& Course, CIS_Grades& Grades); //produces Course, preserves Grades void Parse_Grade_File_Line(cString& line, Student& student, CIS_Grades& Grades); //produces student, produces Grades void Get_Data_Set(cString& line, int& pos, int kind, CIS_Grades& Grades); //alters line, Grades float StrToNumber(cString& s, int& pos); int main(int argc, char** argv) { ifstream grades, gradeinfo; ofstream output; CIS_Course Course; CIS_Grades Grades; //Check number of command line parameters #if DEBUG == 0 if(argc != 4) { cerr << "usage: " << argv[0] << " grade-file gradeinfo-file outfile\n"; return 1; } //Open files grades.open(argv[1]); if(grades.fail()) { cerr << "Error opening " << argv[1] << endl; return 2; } gradeinfo.open(argv[2]); if(gradeinfo.fail()) { cerr << "Error opening " << argv[2] << endl; return 2; } output.open(argv[3], ios::trunc, filebuf::openprot); if(output.fail()) { cerr << "Error opening " << argv[3] << endl; return 2; } #else grades.open("c:\\temp\\xgrades.csv"); gradeinfo.open("c:\\temp\\GradeInfo2.csv"); output.open("c:\\temp\\tables.htm"); #endif //END Open files //Do work Read_GradeInfo_File(gradeinfo, Course, Grades); Read_Grade_File(grades, Course, Grades); Course.Auto_Assign_Aliases(); Course.Sort_Students_By_Alias(); //Course.Output(output); output << "\n\n"; Course.Output_Info(output); //Course.Output_Student_List(output); Course.Output_Grades(output); output << "\n\n"; //END Do work //Close files grades.close(); gradeinfo.close(); output.close(); //END Close files return 0; } void Read_GradeInfo_File(ifstream& in, CIS_Course& Course, CIS_Grades& Grades) { Grader_Info g; cString line, s; cString name, email; int pos = 0; int hw,cl,lb,ts; //First line contains the type in >> line; hw = static_cast(StrToNumber(line,pos)); Course.Set_Type(hw); //Get the numbers of the carefully graded homeworks in >> line; pos = 0; for(int i = 0; i < NUM_CGHW; i++) { Grades.cghw(i) = static_cast(StrToNumber(line,pos)); pos++; //skip the comma } //Get the number of homeworks, closed labs, labs, and tests pos = 0; in >> line; hw = static_cast(StrToNumber(line,pos)); pos++; cl = static_cast(StrToNumber(line,pos)); pos++; lb = static_cast(StrToNumber(line,pos)); pos++; ts = static_cast(StrToNumber(line,pos)); Grades.Set_NUMs(hw,cl,lb,ts); if(in.eof()) return; if(Course.Type() > 1) { in >> line; pos = 0; if(static_cast(StrToNumber(line,pos)) == 1) //Yes, add stats { Course.Set_Stats(true); }else{ Course.Set_Stats(false); } if(in.eof()) return; //May need to in.ignore(1,'\n'); here pos = 0; in >> line; //course name while(pos < line.Length() && line[pos] != ',') { pos++; } while(pos < line.Length()) { char c; line.Remove(pos,c); } Course.Swap_Name(line); } if(Course.Type() > 1) { in >> s; //year pos = 0; hw = static_cast(StrToNumber(s,pos)); in >> s; //quarter pos = 0; cl = static_cast(StrToNumber(s,pos)); Course.Set_Time_Offered(hw,cl); } if(Course.Type() == 2) { in >> s; //instructor name pos = 0; while(pos < s.Length() && s[pos] != ',') { pos++; } while(pos < s.Length()) { char c; s.Remove(pos,c); } cString tmp; Course.Swap_Info(line,s,hw,cl); }else if(Course.Type() == 3) { in >> s; //instructor name and email address pos = 0; //Get instructor name while(pos < s.Length() && s[pos] != ',') { name.Add(name.Length(),s[pos++]); } pos++; //skip the comma //Get instructor email address while(pos < s.Length() && s[pos] != ',') //check for comma just in case... { email.Add(email.Length(),s[pos++]); } Course.Swap_Instructor(name); Course.Swap_Instructor_Email(email); while(!in.eof()) { in >> s; //Grader name and email address //Get grader name pos = 0; while(pos < s.Length() && s[pos] != ',') { name.Add(name.Length(),s[pos++]); } pos++; //skip the comma //Get grader email address while(pos < s.Length() && s[pos] != ',') //check for comma just in case... { email.Add(email.Length(),s[pos++]); } if(pos == 1) //that means nothing happened break; g.x() &= name; g.y() &= email; Course.Add_Grader_Info(g); } } } void Read_Grade_File(ifstream& in, CIS_Course& Course, CIS_Grades& Grades) { cString line; Student student; in >> line; //no data on the first line while(!in.eof()) { in >> line; if(line.Length() == 0) break; //paranoid test Parse_Grade_File_Line(line,student,Grades); Course.Add_Student(student,Grades); } } void Parse_Grade_File_Line(cString& line, Student& student, CIS_Grades& Grades) { cString s; int spos; int pos = 0; //First char. is a double quote pos++; //Get LName spos = 0; while(line[pos] != ',') { s.Add(spos++,line[pos++]); } student.Swap_LName(s); pos++; //skip the comma while(line[pos] == ' ') pos++; //skip the whitespace //Get FName s.Clear(); spos = 0; while(line[pos] != '\"') { s.Add(spos++,line[pos++]); } student.Swap_FName(s); pos++; //skip the double quote pos++; //skip the comma while(line[pos] == ' ')pos++; //skip the whitespace //Get Login s.Clear(); spos = 0; while(line[pos] != ',') { s.Add(spos++,line[pos++]); } student.Swap_Login(s); pos++; //skip the comma while(line[pos] == ' ') pos++; //skip the whitespace //Get Alias s.Clear(); spos = 0; while(line[pos] != ',') //this could be empty { s.Add(spos++,line[pos++]); } student.Swap_Alias(s); pos++; //skip the comma pos++; //skip the next comma //Ok, now comes the grades //Get grades Grades.Set_NUMs(); Get_Data_Set(line,pos,HW_KIND,Grades); pos++; //skip the extra comma between data sets Get_Data_Set(line,pos,CL_KIND,Grades); pos++; Get_Data_Set(line,pos,LB_KIND,Grades); pos++; Get_Data_Set(line,pos,TS_KIND,Grades); pos++; //this probably isn't necessary //END Get grades } void Get_Data_Set(cString& line, int& pos, int kind, CIS_Grades& Grades) { cString score;//THIS LINE IS CAUSING A SEGMENTATION FAULT int count = 0; while(count < Grades.Get_NUM(kind) && pos < line.Length()) { //default Score is NO_GRADE if(line[pos] != ',') { Grades.Score(kind,count) = StrToNumber(line,pos); }else{ Grades.Score(kind,count) = NO_GRADE; } count++; pos++; //skip the comma } } float StrToNumber(String& s, int& pos) { float result = 0; float neg = 1.0; int n = 10; int factor = 10; int oldpos = pos; if(s[pos] == '-') { neg *= -1.0; pos++; }else if(s[pos] == '+') { pos++; } while(s[pos] >= '0' && s[pos] <= '9') { result = result * 10.0f + static_cast(s[pos] - '0'); pos++; } if(s[pos] == '.') //then there's a fractional part { pos++; //advance to next character while(s[pos] >= '0' && s[pos] <= '9') { result += (static_cast(s[pos] - '0') / static_cast(n)); n *= factor; pos++; } } if(oldpos == pos) return NO_GRADE; return neg*result; }