Vectors, Structs, classes, and strings not properly assigned?

Write your question here.
I'm not sure where the exact issue is. The part of the program I'm on is a class that will manage a list of Employees. The employees are held in a certain file, and are to be retrieved upon starting the application. If the file is empty, a default admin is created with username admin, password 0000.

I made a function to load in the employees, and was attempting to test it. I wanted to use a friend function for testing purposes, so it can access and double check private items in the EmployeeManager class.


This is the current class definition:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  class EmployeeManager {
	public:
		EmployeeManager(string filename); // Constructor
		EmployeeManager(); //Default constructor
		bool verifyLogin(string username, string password); //Verifies login information
		bool changePassword(string username, string oldPass, string newPass); //change password
		bool isAdmin(string username); //Verify if user is admin
		bool addEmployee(string username, string password, bool isAdmin); //add Employee
		bool deleteEmployee(string username);
		void displayEmployees(); //Displays employee list. Might overload << instead.
		friend void test_loadEmployees(); //Test function
	private:
		//Struct to hold employee information.
		struct Employee { 
			string username;
			string password;
			bool admin; //True if admin, false if not
		};
		typedef Employee* EmployeePtr; //Points to employees. Used for dynamic array.
		//EmployeePtr employeeList;
		vector<EmployeePtr> employeeList;
		string employeeFile; //File of employees
		void loadEmployees(); //Loads employees into employeeList
		void saveEmployees(); //save employeeList into employee file
		static const string DEFAULT_FILE;
};


The class contains a struct for employees. Originally, employeeList was of the Employee type, but I wasn't sure if that was causing an issue, so now I made a pointer for Employee, and the employeeList is full of employeePtrs.

This is my current function for "loadEmployees"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

//Loads employees from employeeFile. If no employees, create default admin with password 0000.
//If fails to open, display error message.
void EmployeeManager::loadEmployees() {
	ifstream inStream;
	inStream.open((char*)employeeFile.c_str());
	//If cannot find or open, display error.
	if (inStream.fail()) {
		cout << "File open failed. Please use staff.txt\n";
	}
	//Retrieve employee info
	//MIGHT NEED TO COME BACK IF EMPLOYEES ARE REPEATING
	//if so neeed to make "new" temp Emp.
	EmployeePtr tempEmp;
	int tempBool;
	while (!inStream.eof()) {
		tempEmp = new Employee;
		inStream >> tempEmp->username;
		inStream >> tempEmp->password;
		inStream >> tempBool;
		//Sets admin status. Saved as 0 or 1. 0 = not admin, 1 = admin.
		if (tempBool == 0) {
			tempEmp->admin = false;
		}
		else {
			tempEmp->admin = true;
		}
		employeeList.push_back(tempEmp);
	}
	//If nothing in file, create default admin
	if (employeeList.empty()) {
		tempEmp = new Employee;
		tempEmp->username = "admin";
		tempEmp->password = "0000";
		tempEmp->admin = true;
		employeeList.push_back(tempEmp);
	}
	//For testing
	cout << employeeList.size();
	cout << employeeList[0]->username << endl;
	cout << employeeList[0]->password << endl;
	cout << employeeList[0]->admin << endl;
}


I made it start outputing the stuff to try and see where the issue was (in my test function or in this function).

When it prints it out, well, it doesn't. It prints out "1" a blank line, and then "0".

This leads me to believe the issue is with the function and not the testing function. For some reason, username and password are definitely not getting set.
You aren't testing for end-of-file correctly. The eof condition is first detected by an input statement so you need to test the input statement directly to catch eof as soon as it happens.

What you are currently doing is testing for eof first, then reading from the file, which may detect eof, but you're already committed to creating and pushing a new object with garbage values.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// You should make a constructor for Employee:
Employee(string u, string p, bool a) : username(u), password(p), admin(a) {}

void EmployeeManager::loadEmployees() {
    ifstream in(employeeFile.c_str());
    if (in) {
        string u, p;
        int a;
        while (in >> u >> p >> a)
            employeeList.push_back(new Employee(u, p, a!=0));
    }
    if (employeeList.size() == 0)
        employeeList.push_back(new Employee("admin", "0000", true));
}

Last edited on
Thank you! That was the issue. I knew it had to be something dumb. Thanks for the tip about the constructor too. My code looks much nicer now :)
Topic archived. No new replies allowed.