I am not exactly sure what information is relevant, so my apologies for any useless/redundant information.
On my Mac (Snow Leopard 10.6.8) with xCode (gcc) compiled and run through the terminal the following works fine (ignore code and continue reading):
#include <istream>
#include <string>
#include <iostream>
#include <fstream>
enum Year {FRESHMAN, SOPHMORE, JUNIOR, SENIOR};
const std::string YearNames[4] = {"Freshman", "Sophmore", "Junior", "Senior"};
enum Semester {FIRST, SECOND};
const std::string SemesterNames[2] = {"First", "Second"};
// Replace the following comments with the appropriate member definition:
struct Student {
std::string name;
std::string studentID;
Year year;
Semester semester;
float gpa;
};
void printStudents(Student *students, int numStudents);
Student *readStudents(std::ifstream &inp, int &numStudents);
void writeStudents(std::ofstream &outp, Student *students, int numStudents);
const int PRINTSTUDENTS = 1;
const int READSTUDENTS = 2;
const int WRITESTUDENTS = 3;
const int EXIT = 4;
int main(int argc, char *argv[]) {
char fileName[50];
char dummy[1];
int numStudents = 0;
Student *students = NULL;
int choice = 0;
do {
std::cout << "Menu" << std::endl;
std::cout << PRINTSTUDENTS << ") Print students" << std::endl;
std::cout << READSTUDENTS << ") Read a new file" << std::endl;
std::cout << WRITESTUDENTS << ") Write the file" << std::endl;
std::cout << EXIT << ") EXIT" << std::endl;
std::cout << "Choose: ";
std::cin >> choice;
std::cin.ignore();
switch (choice) {
case PRINTSTUDENTS:
printStudents(students, numStudents);
break;
case READSTUDENTS:
std::cout << "Please enter a file name: ";
std::cin.getline(fileName, 50);
{
std::ifstream inp(fileName);
if (!inp) {
std::cerr << "Cannot open student file" << std::endl;
}
// Put code here to get rid of the student array if
// the array already exists. YOU MUST DO THIS, or
// you will have a memory leak (and get points off).
if (students) {
delete [] students;
students = readStudents(inp, numStudents);
} else {
students = readStudents(inp, numStudents);
}
}
break;
case WRITESTUDENTS:
std::cout << "Please enter a file name: ";
std::cin.getline(fileName, 50);
{
std::ofstream outp(fileName);
if (!outp) {
std::cerr << "Cannot open student file" << std::endl;
}
writeStudents(outp, students, numStudents);
}
break;
case EXIT:
break;
default:
std::cout << "You entered and invalid choice." << std::endl;
}
if (choice != EXIT) {
std::cout << "Please press <enter> to continue..." << std::endl;
std::cin.getline(dummy, 1);
}
} while (choice != EXIT);
return 0;
}
// definition of printStudents() goes here:
void printStudents(Student *students, int numStudents) {
for (int i = 0; i < numStudents; i++) {
std::cout << students[i].name << std::endl;
std::cout << " " << students[i].studentID << std::endl;
if (students[i].year == FRESHMAN) {
std::cout << " " << YearNames[FRESHMAN] << std::endl;
} else if (students[i].year == SOPHMORE) {
std::cout << " " << YearNames[SOPHMORE] << std::endl;
} else if (students[i].year == JUNIOR) {
std::cout << " " << YearNames[JUNIOR] << std::endl;
} else {
std::cout << " " << YearNames[SENIOR] << std::endl;
}
students[i].semester == FIRST ? std::cout << " " << SemesterNames[FIRST] << std::endl : std::cout << " " << SemesterNames[SECOND] << std::endl;
std::cout << " " << students[i].gpa << std::endl;
}
}
// definition of readStudents goes here:
Student *readStudents(std::ifstream &inp, int &numStudents) {
inp >> numStudents; inp.ignore();
Student *ptr = new Student[numStudents];
int temp = 0;
for (int i = 0; i < numStudents; i++) {
getline(inp, ptr[i].name);
getline(inp, ptr[i].studentID);
inp >> temp;
ptr[i].year = static_cast<Year>(temp);
inp >> temp;
ptr[i].semester = static_cast<Semester>(temp);
inp >> ptr[i].gpa; inp.ignore();
}
inp.ignore();
return ptr;
}
// definition of writeStudents goes here:
void writeStudents(std::ofstream &outp, Student *students, int numStudents) {
outp << numStudents << std::endl;
for (int i = 0; i < numStudents; i++) {
outp << students[i].name << std::endl;
outp << students[i].studentID << std::endl;
outp << students[i].year << std::endl;
outp << students[i].semester << std::endl;
outp << students[i].gpa << std::endl;
}
}
However, on Windows 7 (not sure about which release) with cygwin also compiled and run through the terminal, it is not correctly reading from the file.
The content of the file:
2
John Doe
T00001264
0
1
0.00
Jane Doe
T00012345
3
0
3.62
The ideal output when calling printStudents:
John Doe
T00001264
0
1
0.00
Jane Doe
T00012345
3
0
3.62
What I get on Windows:
John Doe
0
0
0
0
0
0
So my obvious questions are why and how do I correct this? Also, am I deallocating memory correctly on line 67? I would like to just use strings so I wouldn't have to worry about clearing the input buffer, however the assignment is to complete the code my professor provided. Any other input, is of course, more than welcome.
Regards,
Arkinder