Vector of class objects

I am having trouble getting this code to work and I cannot figure out for the life of me what is wrong. I am getting no error messages, just when I run, it gets to a certain point and then just pauses and the program crashes. I really need some help. The program is supposed to read in accounts from a file and run them through a factory function that spits out class objects into a vector of class objects. They will then run through an update balance function that is a virtual function and then they will output. I am having trouble getting the last two parts to work. Any help would be great. Here is my code it is kind of long so it may be in 2 posts.


This is the file they are being read from
account2.dat


1234567890Fred Murtz C00002000.01
9237405759Nolan Ryan A07237895.75
5285064395Debbie Schneiderman C00201537.31
5839659462Freidman Hochstrasser A00048392.42
9587498357Bayern Richard E00003457.12
7395659299Milhouse Van Houten N00000002.85
2956294386Julian Schwinger B00335821.93
9765324598Joanne Bryant B08459873.08
4385638273Richard Ames A00008468.74


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#include"application.h"
#include<iostream>
using namespace std;
using application_class::application;

int main(){
	try{
		application app; 
		return app.run();
	}catch(...){exception_main();}
	
}



application.h
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
#include<fstream>
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include"account.h"
#include"exceptionHandling.h"
using namespace exception_handling;
using namespace std;
using account_class::account;


#ifndef _APPLICATION_CLASS_
#define _APPLICATION_CLASS_

namespace application_class{

class application{
private:
	void outputReport(ostream& report);
	void get_accounts(istream& s);
	void balanceUpdate();
	vector<account*> accounts;
public:
	void run();
};
}
#endif _APPLICATION_CLASS_ 



application.cpp
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
45
46
47
48
#include"factoryFunction.h"
#include"application.h"
#include"accountInfo.h"
using namespace account_info;
using application_class::application;


void application::balanceUpdate(){
	for(vector<account*>::iterator i=accounts.begin(); i!= accounts.end(); ++i){
		(*i)->update_balance();
	}
}
	
void application::outputReport(ostream& report){
	for(vector<account*>::iterator i=accounts.begin(); i!= accounts.end(); ++i){
		(*i)->outputAccount(report);
	}
}

void application::get_accounts(istream& s){
	factoryFunction factory;
		while(s.peek() != EOF){
			accounts.push_back(factory.inputAccounts(s));
		}
}

void application::run(){
		try{
		
		ifstream accountRead("account2.dat");
		if(!accountRead){
			throw exception_one();
		}
		ofstream report("report2.txt");
		if(!report){
			throw exception_two();
		}
		get_accounts(accountRead);
		balanceUpdate();
		cout << accounts.size()<<"\n";
		outputReport(report);
		
		
		
		}catch(exception_one& one){cout<<"Error 2201: "<<one.what();
		}catch(exception_two& two){cout<<"Error 2202: "<<two.what();
		}
	}



factoryFunction.h
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include<fstream>
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include"account.h"
#include"accountInfo.h"
#include "exceptionHandling.h"
#include"balancedAccount.h"
#include"serviceAccount.h"
#include"bonusAccount.h"
#include"simpleAccount.h"
using namespace exception_handling;
using namespace std;
using namespace account_info;
using account_class::account;
using balanced_account::balancedAccount;
using service_account::serviceAccount;
using bonus_account::bonusAccount;
using simple_account::simpleAccount;

		void outputTest(char e, string a, string b, string c, double d){
			cout << e << " ,"<< a <<" ,"<< b <<" ,"<< c <<" ,"<< d <<'\n';
		}

class factoryFunction{
private:
	string first;
	string last;
	string accountCode;
	double balance;
	char type;
public:
	account* inputAccounts(istream& s){
		for(int i=1; i<2; ++i){
		try{
			accountCode = get_accountCode(s, 10);
			first = get_info(s, 15);
			last = get_info(s, 25);
			type = s.get();
			s >> balance;
			if(s.peek()!='\n'){
				throw input_error_exception();
			}
			s.ignore();
			outputTest(type, accountCode, last, first, balance);
			if(type == 'A'||type == 'B'||type == 'C'||type == 'D'){
			switch(type){
				case 1:
					if (type == 'A'){
						return new simpleAccount(accountCode, first, last, balance);
					}
				case 2:
					if (type == 'B'){
						return new bonusAccount(accountCode, first, last, balance);
					}
				case 3:
					if (type == 'C'){
						return new serviceAccount(accountCode, first, last, balance);
					}
				case 4:
					if (type == 'D'){
						return new balancedAccount(accountCode, first, last, balance);
					}
				case 5:
					if (type == 'X'){
						--i;
					}
			}
			}else{
				throw invalid_account_type_exception(accountCode, type);
			}
		}catch(input_error_exception& three){ cout<< "Error 2203: ", three.what();
		}catch(invalid_account_type_exception& invalid){ cout << "Error 2205: \n"; invalid.invalid_account(); --i;}
		}
		return '\0';
	}
};


account.h
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
#include<string>
#include<iostream>
#include<cstdlib>
#include<vector>
using namespace std;
#ifndef _ACCOUNT_CLASS_
#define _ACCOUNT_CLASS_
namespace account_class{

class account{
private:
	string account_code;
	string first_name;
	string last_name;
	double balance;
public:
	account(){};

	virtual void update_balance() = 0;
	virtual char type() = 0;
	virtual void outputAccount(ostream& report) = 0;
};

	
}
#endif _ACCOUNT_CLASS_ 


simpleAccount.h
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
#include<string>
#include<iostream>
#include<cstdlib>
#include<vector>
#include"account.h"
using account_class::account;
using namespace std;
#ifndef _SIMPLE_ACCOUNT_CLASS_
#define _SIMPLE_ACCOUNT_CLASS_
namespace simple_account{

class simpleAccount: public account{
private:
	string account_code;
	string first_name;
	string last_name;
	double balance;
public:
	simpleAccount(string init_account, string init_first, string init_last, double init_balance): 
	  account_code(init_account), first_name(init_first), last_name(init_last), balance(init_balance){};
private:
	void update_balance(){
		
		balance *= 1.05;
	}
	char type(){
		return 'A';
	}
	void outputAccount(ostream& report){
		report << last_name << "\n";
	}
};

bonusAccount.h
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
#include<string>
#include<iostream>
#include<cstdlib>
#include<vector>
#include"account.h"
using account_class::account;
using namespace std;
#ifndef _BONUS_ACCOUNT_CLASS_
#define _BONUS_ACCOUNT_CLASS_
namespace bonus_account{

class bonusAccount: public account{
private:
	string account_code;
	string first_name;
	string last_name;
	double balance;
public:
	bonusAccount(string init_account, string init_first, string init_last, double init_balance): 
	  account_code(init_account), first_name(init_first), last_name(init_last), balance(init_balance){};
private:
	void update_balance(){
		balance *= balance > 5000 ? 1.06 : 1.04;
	}
	char type(){
		return 'B';
	}
	void outputAccount(ostream& report){
		report << last_name<< "\n";
		 
	}

};
}
#endif _BONUS_ACCOUNT_CLASS_ 


serviceAccount.h
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
#include<string>
#include<iostream>
#include<cstdlib>
#include<vector>
#include"account.h"
using account_class::account;
using namespace std;
#ifndef _SERVICE_ACCOUNT_CLASS_
#define _SERVICE_ACCOUNT_CLASS_
namespace service_account{

class serviceAccount: public account{
private:
	string account_code;
	string first_name;
	string last_name;
	double balance;
public:
	serviceAccount(string init_account, string init_first, string init_last, double init_balance): 
	  account_code(init_account), first_name(init_first), last_name(init_last), balance(init_balance){};
private:
	void update_balance(){
		balance = (balance - 5.0) * 1.03;
	}
	char type(){
		return 'C';
	}
	void outputAccount(ostream& report){
		report << last_name<< "\n";
		
	}

};
}
#endif _SERVICE_ACCOUNT_CLASS_ 

Last edited on
Part 2 of my code:



balancedAccount.h
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
#include<string>
#include<iostream>
#include<cstdlib>
#include<vector>
#include"account.h"
using account_class::account;
using namespace std;
#ifndef _BALANCED_ACCOUNT_CLASS_
#define _BALANCED_ACCOUNT_CLASS_
namespace balanced_account{

class balancedAccount: public account{
private:
	string account_code;
	string first_name;
	string last_name;
	double balance;
public:
	balancedAccount(string init_account, string init_first, string init_last, double init_balance): 
	  account_code(init_account), first_name(init_first), last_name(init_last), balance(init_balance){};
private:
	void update_balance(){
		balance = balance > 500.0 ? balance * 1.05 : (balance - 10.0) * 1.04;
	}
	char type(){
		return 'D';
	}
	void outputAccount(ostream& report){
		report << last_name<< "\n";

	}

};
}
#endif _BALANCED_ACCOUNT_CLASS_ 


exceptionHandling.h
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
45
46
47
48
49
50
51
52
53
54
#include<stdexcept>
#include<iostream>
#include"time.h"
using std::cout;
using std::exception;
using std::runtime_error;
#ifndef _EXCEPTION_HANDLING_
#define _EXCEPTION_HANDLING_

namespace exception_handling{

class exception_one:public runtime_error{
public:
	exception_one():runtime_error("File account.dat was unable to be opened\n"){};

};
class exception_two:public runtime_error{
public:
	exception_two():runtime_error("An error occured trying to open report.txt\n"){};

};

class input_error_exception:public runtime_error{
public:
	input_error_exception():runtime_error("An error occured while reading in data from account file.\n Please make sure all data is correct\n"){};
};

class invalid_account_type_exception:public exception{
private:
	string accountCode;
	char type;
	char date[9];
	char time[9];
public:
	invalid_account_type_exception(string init_account, char init_type): accountCode(init_account), type(init_type){};
	
	void invalid_account(){
		_strdate_s(date);
		_strtime_s(time);
		ofstream errorReport("account.log", ios::app);
		errorReport <<"Date: "<< date <<" Time: "<< time << "\nAn invalid account type " << type << " was found while reading account #: " << accountCode 
			<< "\n\tAccount was skipped, Please check information and fix accordingly.\n"<<
			"-------------------------------------------------------------------------------------------\n\n";
		errorReport.close();
	}
};

class exception_main:public runtime_error{
public:
	exception_main():runtime_error("Unknown Error Caught in the last catch"){};

};
}
#endif _EXCEPTION_HANDLING_ 


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
45
46
47
48
49
50
51
52
53
54
55
56
accountInfo.h
#include<fstream>
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include"exceptionHandling.h"
using namespace std;
using namespace exception_handling;
#ifndef _ACCOUNT_INFO_
#define _ACCOUNT_INFO_
namespace account_info{

istream &get(istream &s, string &value, size_t count, char delim = '\n') {
	value.erase();
	for (;;) {
		int	c = s.peek();

		if (c == EOF) {
			s.clear(std::ios::eofbit | s.rdstate()); 
			break;
		}
		if (static_cast<char>(c) == delim || count-- == 0) {
			break;
		}
		value.append(1, static_cast<char>(c));
		s.ignore();
	}
	return s;
}
string trim_right(const string& str) {
	string::const_iterator i = str.end();
	while (i != str.begin() && isspace(*(i - 1))) {
		--i;
	}
	return string(str.begin(), i);
}
string get_info(istream& s, int size){
	string r;
	get(s, r, size);
	r = trim_right(r);
	return r;
}
string get_accountCode(istream& s, int size){
	string r;
	get(s, r, size);
	return r;
}
string get_type(istream& s, int size){
	string r;
	get(s, r, size);
	return r;
}
}
#endif _ACCOUNT_INFO_
Last edited on
Any help from anyone?
"Here is my program, please fix it" posts are hard to respond to. Especially when the code lacks comments, is not in code tags, spans multiple files, and is very long.

Help us out by doing some debugging on your own:

it gets to a certain point and then just pauses and the program crashes


What point? Find out where the program locks up.

Do this by setting breakpoints around your code and stepping through them. Or if you don't have a debugging IDE, you can throw cout lines in there to mark what code is running.
Well I did debug it as far as I can. There are no errors in the compiler. I added a cout to print out what it reads in and it reads in everything fine and then displays that the vector<account*> size is 7 which is correct. i believe the problem is when it trys to use the balance update that is located in the application.cpp page. That function and the output function right underneath it is where it crashes because if I take the codes to iterate through the vector out of each then it runs through the program fine. So either I read in the data to the vector wrong or I am iterating it wrong. Sorry I have not commented anything out yet because I am not finished. I just got very frustrated and couldnt think of anything else to do.
Also if someone can tell me how to put them in code tags I will
Okay sorry about that now I know and my code is tagged. I dont want to necessarily have my code written for me because I did write this myself. I just need some help debugging it. I am still fairly new and do not know how to fix all the problems I have yet
I am wondering if my vector of class objects is being inserted incorrectly. Is this the correct way of doing is?
factoryFunction.h
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<fstream>
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include"account.h"
#include"accountInfo.h"
#include "exceptionHandling.h"
#include"balancedAccount.h"
#include"serviceAccount.h"
#include"bonusAccount.h"
#include"simpleAccount.h"
using namespace exception_handling;
using namespace std;
using namespace account_info;
using account_class::account;
using balanced_account::balancedAccount;
using service_account::serviceAccount;
using bonus_account::bonusAccount;
using simple_account::simpleAccount;

		void outputTest(char e, string a, string b, string c, double d){
			cout << e << " ,"<< a <<" ,"<< b <<" ,"<< c <<" ,"<< d <<'\n';
		}

class factoryFunction{
private:
	string first;
	string last;
	string accountCode;
	double balance;
	char type;
public:
	account* inputAccounts(istream& s){
		for(int i=1; i<2; ++i){
		try{
			accountCode = get_accountCode(s, 10);
			first = get_info(s, 15);
			last = get_info(s, 25);
			type = s.get();
			s >> balance;
			if(s.peek()!='\n'){
				throw input_error_exception();
			}
			s.ignore();
			outputTest(type, accountCode, last, first, balance);
			if(type == 'A'||type == 'B'||type == 'C'||type == 'D'){
			switch(type){
				case 1:
					if (type == 'A'){
						return new simpleAccount(accountCode, first, last, balance);
					}
				case 2:
					if (type == 'B'){
						return new bonusAccount(accountCode, first, last, balance);
					}
				case 3:
					if (type == 'C'){
						return new serviceAccount(accountCode, first, last, balance);
					}
				case 4:
					if (type == 'D'){
						return new balancedAccount(accountCode, first, last, balance);
					}
				case 5:
					if (type == 'X'){
						--i;
					}
			}
			}else{
				throw invalid_account_type_exception(accountCode, type);
			}
		}catch(input_error_exception& three){ cout<< "Error 2203: ", three.what();
		}catch(invalid_account_type_exception& invalid){ cout << "Error 2205: \n"; invalid.invalid_account(); --i;}
		}
		return '\0';
	}
};
Well I gave it a quick once over and didn't see anything that would be causing the problem.

I'll try and compile it and run it when I get home from work tonight. Maybe I'll find something then.


EDIT:

nevermind -- I went out with friends last night instead, and this morning I don't really feel like playing around with this. Sorry =(
Last edited on
Thanks alot I appreciate that
Okay after hours of changing trying different things I figured it out. First my switch statement is not written completely correctly and my loop to kick out invalid code types is still sending a null pointer to the vector account pointers. So I fixed it. Here is my new code for that page
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<fstream>
#include<iostream>
#include<string>
#include<cstdlib>
#include<vector>
#include"account.h"
#include"accountInfo.h"
#include "exceptionHandling.h"
#include"balancedAccount.h"
#include"serviceAccount.h"
#include"bonusAccount.h"
#include"simpleAccount.h"
using namespace exception_handling;
using namespace std;
using namespace account_info;
using account_class::account;
using balanced_account::balancedAccount;
using service_account::serviceAccount;
using bonus_account::bonusAccount;
using simple_account::simpleAccount;

class factoryFunction{
private:
	string first;
	string last;
	string accountCode;
	double balance;
	char type;
public:
	account* inputAccounts(istream& s){
		for(int i=1; i<2; ++i){
		try{
			accountCode = get_accountCode(s, 10);
			first = get_info(s, 15);
			last = get_info(s, 25);
			type = s.get();
			s >> balance;
			if(s.peek()!='\n'){
				throw input_error_exception();
			}
			s.ignore();
			switch(type){
				case 'A':
						return new simpleAccount(accountCode, first, last, balance);
					
				case 'B':
						return new bonusAccount(accountCode, first, last, balance);
					
				case 'C':
						return new serviceAccount(accountCode, first, last, balance);
					
				case 'D':
						return new balancedAccount(accountCode, first, last, balance);

				case 'X':
					throw account_deletion_log(accountCode, last, first);
				default:
					throw invalid_account_type_exception(accountCode, type);
			}
		}catch(account_deletion_log& log){cout << "Account#: "<< accountCode <<" has been logged and deleted\n"; log.accountDeletion(); --i;
		}catch(input_error_exception& three){ cout<< "Error 2203: ", three.what();
		}catch(invalid_account_type_exception& invalid){ cout << "Error 2205: Invalid Code Type\n"; invalid.invalid_account(); --i;}
		}
	}
};
Topic archived. No new replies allowed.