// Source: "Software Design ...", John A Robinson, Newnes, 2004, page 106. #include #include #include using namespace std; #define MAXSTUDENTS 80 #define MAXNAMELENGTH 30 struct student { char name[MAXNAMELENGTH]; long id; float mark; }; float average_mark(int num_students, student *p); int load_data(char *fname, student **pp); int main(int argc, char **argv) { student *syde321; // Will point to the base of the array of structures int num_students; if (argc != 2) { cerr << "Usage: average filename\n"; return(-1); } if ((num_students = load_data(*(argv+1),&syde321)) < 0) return(-1); cout << "Average was " << average_mark(num_students, syde321) << "\n"; return(0); } float average_mark(int num_students, student *p) { int i; float sum_marks; sum_marks = 0.0; for (i = 0; i < num_students; i++) sum_marks += p[i].mark; // Remember, a pointer passed to a function can be treated // like the start address of an array. return(sum_marks/num_students); } int load_data(char *fname, student **pp) { char c; student *memory; unsigned int numstudents; ifstream in(fname); if (!in) { cerr << "Can't open " << fname << " for reading\n"; return(-1); } in >> numstudents; if (numstudents > MAXSTUDENTS) { cerr << "Too many database entries\n"; return(-1); } memory = new student[numstudents]; // Memory is allocated here // Don't catch bad_alloc exception from new: Just exit if memory exhausted. // Write into student pointer *pp = memory; for(int i = 0; i < numstudents; i++) { in >> memory[i].name; in >> memory[i].id; in >> memory[i].mark; } in.close(); memory[numstudents].id = 0; // Sentinel return(numstudents); }