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

Recommended Answers

All 5 Replies

Your program seems to work correctly for me on Windows 7 and using VC++ 2010 Express.

-_- Wonderful. Well, thanks for taking a look. I guess I will just wait and ask my professor about it.

Regards,
Arkinder

Curiously, when using Code::Blocks 10.5 (MinGW GCC 4.4.1), I get the following result from the same dataset:

John Doe
 T00001264
 Freshman
 Second
 0
Jane Doe
 T00012345
 Senior
 First
 3.62

I'm not sure what the cause of the discrepancy in the results is.

So would it be safe to assume that the problem is either in cygwin or the specific machine? My professor is going to look at it later today, so I'll post whatever he thinks the error is.

Thanks,
Arkinder

It turns out that it was cygwin. During installation it gives you the option of using Unix line endings or DOS line endings. I suppose that this makes sense because cygwin is a Unix Shell IDE. Anyways, the solution is running the installer again and selecting the DOS option.

Regards,
Arkinder

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.