The<cctype>header provides useful functions for manipulating charactor data:
isspace(c) isalpha(c) isdigit(c) isalnum(c) ispunct(c) // punctuation charactor isupper(c) islower(c) toupper(c) tolower(c)split.h
#ifndef GUARD_split_h #define GUARD_split_h #include <vector> #include <string> std::vector<std::string> split(const std::string&); #endifsplit.cpp
//source file split-related #include<cctype> #include "split.h" using std::string; using std::vector; vector<string> split(const string& s) { vector<string> ret; typedef vector<string>::size_type s_sz; s_sz i = 0; s_sz j = 0; while (i != s.size()) { while (i != s.size() && isspace(s[i])) ++i; j = i; while (j != s.size() && !isspace(s[j])) ++j; if (i != j) { ret.push_back(s.substr(i,j - i)); i = j; } } return ret; }Student_info.h Student_info.cpp grade.h(median.h) grade.cpp(median.cpp) see Note 4
extract_fails.h
#ifndef GUARD_extract_fails_h #define GUARD_extract_fails_h #include <list> #include "Student_info.h" bool fgrade(const Student_info&); bool pgrade(const Student_info&); std::list<Student_info> extract_fails(std::list<Student_info>&); #endifextract_fails.cpp
#include "grade.h" #include "extract_fails.h" #include "fopgrade.h" #include "Student_info.h" using std::list; bool fgrade(const Student_info& s) { return grade(s) < 60; } bool pgrade(const Student_info& s) { return grade(s) >= 60; } list<Student_info> extract_fails(list<Student_info>& students) { list<Student_info> fails; list<Student_info>::iterator iter = students.begin(); while(iter != students.end()){ if (fgrade(*iter)) { fails.push_back(*iter); iter = students.erase(iter); } else { ++iter; } } return fails; }main.cpp
#include <algorithm> #include <iomanip> // setprecision #include <ios> // streamsize #include <iostream> #include <stdexcept> #include <string> #include "Student_info.h" #include "grade.h" #include "extract_fails.h" using std::list; using std::sort; using std::string; using std::endl; using std::domain_error; using std::cin; using std::cout; using std::max; using std::streamsize; using std::setprecision; using std::list; using std::setw; int main(){ list<Student_info> students; Student_info record; list<Student_info> fail_stus; string::size_type maxlen = 0; // read and store all the students' data // Invariant: students contains all the student records read so far // maxlen contains the length of the longest name in students while (read(cin, record)) { // find length of longest name maxlen = max(maxlen, record.name.size()); students.push_back(record); } // alphabetize the student records sort(students.begin(), students.end(), compare); // write the names and grades for (list<Student_info>::iterator it = students.begin(); it != students.end(); ++it){ // write the name, padded on the right to maxlen + 1 characters record = (*it); cout << record.name << string(maxlen + 1 - record.name.size(), ' '); // compute and write the grade try { double final_grade = grade(record); streamsize prec = cout.precision(); cout << setprecision(3) << final_grade << setprecision(prec); } catch (domain_error e) { cout << e.what(); } cout << endl; } cout << "print the students who fail the exam!" << endl; fail_stus = extract_fails(students); for (list<Student_info>::iterator it = fail_stus.begin(); it != fail_stus.end(); ++it) { record = *it; cout << record.name << string(maxlen + 1 - record.name.size(), ' '); try { streamsize prec = cout.precision(); cout << setw(4) << setprecision(3) << grade(record) << setprecision(prec); } catch (domain_error e) { cout << e.what(); } cout << endl; } return 0; }