A couple of problems with my code

So I'm a function over form kind of person and my code looks it but I'm having two different problems first a little info on the file I am working on for a programming final project. as it stands it reads in allows for new users to sign up and then prints that account into a txt file like so

100000 1530 Matt Smith 500
100001 456 Drew Carey 500
100002 948 David Tennent 500
100003 1115599 Robin Williams 500

the first is the account number (assigned by the program)
second is a pin the user enters
third and fourth are the users name
and the fifth is a floating balance for their account (initial balance assigned by the program)

after someone is enrolled they can re -launch the program and pull up their account by either the account number or their first and last name. The account search works fine but a similar coded name search does not, it only works if the name you are searching for is the first name on the list (I moved the names around to make sure). once the account is found it prompts for a pin and compares that to the pin for the account (also works). Once verified it currently asks the user for an amount to add to their balance, then creates a new txt file copies the data over until it reaches the accessed account as it gets passed to the new file the balance gets updated. The old file is deleted and the new file gets renamed to the old file name. this part works except that the last account gets read twice (not using eof but instead a do statement with a while .good statement.

In summary
1st issue is name search only ever works for first name in list
2nd issue final line printed twice during file copy

Relevent code follows
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
case 1: // Existing user looking by account number (this works)
                {
                    cout << "Please enter your full account number \n";
                    cin >> accountNumber;
                    fstream account ("accounts.txt", ios::in | ios::out);
                    if(account.is_open())
                    {

                        do
                        {
                            getline(account,input);
                            istringstream iss(input);
                            for(i=0; i<5; i++)
                            {
                                iss >> accountInfo[i];
                            }
                            temp = atoi(accountInfo[0].c_str());
                            if(temp == accountNumber)
                            {
                                cout << "Your account has been found \n";
                                accountFound = true;
                                break;
                            }
                        }while(account.good());
                        if(accountFound == false)
                        {
                            cout <<"Your account was not found \n";
                            return 1;
                        }

                        cout << "Welcome " << accountInfo[2] << " " << accountInfo[3] << endl;
                        cout << "Please enter your pin number \n";
                        temp = atoi(accountInfo[1].c_str());
                        for(i = 0; i < 3; i++)
                        {
                            cin >> pinNumber;
                            if(pinNumber == temp)
                            {
                                cout << "Thank your your account balance is $" << atof(accountInfo[4].c_str()) << endl;
                                balance = atof(accountInfo[4].c_str());
                                accountNumber = atoi(accountInfo[0].c_str());
                                break;
                            }
                            else
                            {
                                cout << "That pin does not match our records you have enter the wrong pin " << (i+1) << " time(s) \n" ;
                                cout << "Please retry your pin \n";
                            }
                            if(i==2)
                            {
                                cout << "You have entered the wrong pin number 3 times program will now close \n";
                                return 1;
                            }
                        }
                        break;
                        account.close();
                    }
                }//exisiting user looking by account number ends here

                case 2: //existing user looking by name starts here (this doesnt work except the first account in the file)
                {
                    cout << "Please enter your first name \n";
                    cin >> firstName;
                    cout << "Please enter your last name \n";
                    cin >> lastName;
                    fstream account ("accounts.txt", ios::in | ios::out);
                    if(account.is_open())
                    {
                        do
                        {
                            getline(account,input);
                            istringstream iss(input);
                            for(i=0; i<5; i++)
                            {
                                iss >> accountInfo[i];
                            }
                            tempFirstName = accountInfo[2];
                            tempLastName = accountInfo[3];
                            if(firstName == tempFirstName && lastName == tempLastName)
                            {
                                cout << "Your account has been found \n";
                                accountFound = true;
                                break;
                            }
                            if(accountFound == false)
                            {
                                cout <<"Your account was not found \n";
                                return 1;
                            }
                        }while(account.good());
                        cout << "Welcome " << accountInfo[2] << " " << accountInfo[3] << endl;
                        cout << "Please enter your pin number \n";
                        temp = atoi(accountInfo[1].c_str());
                        for(i = 0; i < 3; i++)
                        {
                            cin >> pinNumber;
                            if(pinNumber == temp)
                            {
                                cout << "Thank your your account balance is $" << atof(accountInfo[4].c_str()) << endl;
                                balance = atof(accountInfo[4].c_str());
                                break;
                            }
                            else
                            {
                                cout << "That pin does not match our records you have enter the wrong pin " << (i+1) << " time(s) \n" ;
                                cout << "Please retry your pin \n";
                            }
                             if(i==2)
                            {
                                cout << "You have entered the wrong pin number 3 times program will now close \n";
                                return 1;
                            }
                        }
                    }
                    break;
                    account.close();
                } // existing user looking by name ends here 

This is where the file is copied
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
cout << "Now that we have your account number lets adjust your balance enter what to add\n"; //temporary balance updater begins here
    cin >> bet;
    balance += bet;
    fstream account ("accounts.txt", ios::in | ios::out);
    if(account.is_open())
    {
        ofstream tempAccount;
        tempAccount.open ("tempaccounts.txt");
        do
        {
            getline(account,input);
            istringstream iss(input);
            for(i=0; i<5; i++)
            {
                iss >> accountInfo[i];
            }
            temp = atoi(accountInfo[0].c_str());
            if(temp == accountNumber)
            {
                stringstream ss(stringstream::in | stringstream::out);
                ss << balance;
                tempBalance = ss.str();
                accountInfo[4] = tempBalance;
            }
            tempAccount << accountInfo[0] << " " << accountInfo[1] << " " << accountInfo[2] << " " << accountInfo[3] << " " <<  accountInfo[4] << endl;
            if(account.eof())
            {
                break;
            }
        }while(account.good());
    }
    account.close();
    remove ("accounts.txt");
    rename(oldName,newName); //temporary balance updater ends here 

due to character limits I could not post the whole program but any ideas?
I wrote my own version, which you can debug for me. The accountNumber isn't saved right in the file. Also I think I should redesign it. Could you help me please?

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>

struct Account {
	unsigned int accountNumber;
	unsigned int pin;
	std::string firstName;
	std::string lastName;
	float balance;

	bool operator == (const Account &a)
	{
		if (pin != a.pin || firstName != a.firstName || lastName != a.lastName)
			return false;

		return true;
	}

	bool operator != (const Account &a)
	{
		if (pin == a.pin && firstName == a.firstName && lastName == a.lastName)
			return false;

		return true;
	}
};

std::ostream & operator << (std::ostream &os, const Account &a)
{
	os << a.accountNumber << ' ' << a.pin << ' ' << a.firstName
		<< ' ' << a.lastName << ' ' << a.balance << std::endl;
	return os;
}

std::istream & operator >> (std::istream &is, Account &a)
{
	is >> a.accountNumber;
	is >> a.pin;
	is >> a.firstName;
	is >> a.lastName;
	is >> a.balance;
	return is;
}

namespace {
const char *accountsFilename = "accounts.txt";
const char *tempAccountsFilename = "tempAccounts.txt";
unsigned int currentAccountNumber = 1000;
}

int createNewAccount()
{
	Account a;
	std::ofstream outputFile(accountsFilename, std::ios_base::app);

	a.accountNumber = currentAccountNumber++;
	std::cout << " * Input first name: ";
	std::cin >> a.firstName;
	std::cout << " * Input last name: ";
	std::cin >> a.lastName;
	std::cout << " * Input your PIN: ";
	std::cin >> a.pin;
	std::cout << " * Input your balance: ";
	std::cin >> a.balance;

	if (outputFile.is_open())
	{
		outputFile.exceptions(std::ios_base::failbit);
		outputFile << a;
	}
	else
		std::cerr << "Could not open " << accountsFilename
			<< " to save your data." << std::endl;

	return 1;
}

int modifyExistingAccount()
{
	Account user;
	std::ifstream inputFile(accountsFilename);

	std::cout << " * Input first name: ";
	std::cin >> user.firstName;
	std::cout << " * Input last name: ";
	std::cin >> user.lastName;
	std::cout << " * Input your PIN: ";
	std::cin >> user.pin;

	if (inputFile.is_open())
	{
		Account target;

		inputFile.exceptions(std::ios_base::badbit);

		while (inputFile >> target)
			if (user == target)
			{
				user.accountNumber = target.accountNumber;
				std::cout << "Account found!\n >> Input new PIN: ";
				std::cin >> user.pin;
				std::cout << " >> Input new balance: ";
				std::cin >> user.balance;
				inputFile.seekg(0);

				std::ofstream tempFile(tempAccountsFilename);

				if (tempFile.is_open())
				{
					Account tempAccount;

					while (inputFile >> tempAccount && tempAccount != target)
						tempFile << tempAccount;

					tempFile << user;

					while (inputFile >> tempAccount) // copy the rest
						tempFile << tempAccount;

					inputFile.close();
					tempFile.close();
					std::remove(accountsFilename);
					std::rename(tempAccountsFilename, accountsFilename);
					break;
				}
			}
	}
	else
		std::cerr << "Could not open " << accountsFilename
			<< " to read your data." << std::endl;

	return 2;
}

int deleteExistingAccount()
{
	std::cerr << "Not implemented yet!" << std::endl;
	return 3;
}

int monkeyError()
{
	std::cerr << "Input 1, 2 or 3, you monkey." << std::endl;
	return -666;
}

int main()
{
	std::cout << "Pick an action:\n\t1 - Create new account.\n"
		"\t2 - Modify existing account.\n"
		"\t3 - Delete existing account.\n\nChoice: ";

	int choice;

	while (std::cin >> choice)
		switch (choice)
		{
			case 1: return createNewAccount();
			case 2: return modifyExistingAccount();
			case 3: return deleteExistingAccount();
			default: return monkeyError();
		}
}
Ill be honest with you Im not good with structs in c++. personally if the accountNumber is not being saved correctly confirm this by looking directly at the txt file. personally I prefer my way of doing it since I prefer doing things directly rather than trying to trace down an issue with the write process but is everything else being written to the file correctly?

Edit: My previous two problems have been resolved if need be I can post the corrected code
Last edited on
Your code is insanely obtuse. No offense but its very long and almost illegible initially. If you want to get better at structs start thinking in modules and look at OOP. Classes in c++ eclipse c structs in modularity and maintainability. You will help yourself out if you can organize the lengthy code into routines (functions/methods). Now you may be a beginner so don't take what i've said in a wrong way I only mean it to help, but organize your code procedure into small processes or modules before your post it. It will make it easier to debug if you can organize your thoughts into discrete tasks. Try to put more spaces between individual declarations and statements. There was no need for an unnamed namespace in your code, global namespace would be fine, overloading operators for the account struct is unnecessary for a c struct replace struct with "class" instead"
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

#include <iostream>
#include <string.h>

using std::cin;
using std::cout;
using std::string;

class Account 
{   
        private: //prevents access from outside class, use accessor methods instead 

	unsigned int accountNumber;
	unsigned int pin;
	std::string firstName;
	std::string lastName;
	float balance;
/*
      public:

      Account():accountNumber(0),pin(0),firstName(std::string("")),lastName(std:string("")),balance(0.0){
//Done
}

//~Account(){//destructor unnecessary}

   //ERGO:
         unsigned int getAccountNumber()const{return accountNumber;}
         unsigned int getPin()const{return pin;}
         std::string getFirstName()const{return firstName;}
         std::string getLastName()const{return lastName;}
         float getBalance()const{return balance;}

   //Why dont tabs work on this forum????

        void setAccountNumber(unsigned int n)const{accountNumber = n;}
        void setPin(unsigned int p)const{pin = p;}
        void setFirstName( const std::string& name  ){firstName = name;}
        void setLastName(const std::string& name){lastName = name;}
        void setBalance(float b)const{balance = b;}
*/       


	bool operator == (const Account &a)
	{
		if (pin != a.pin || firstName != a.firstName || lastName != a.lastName)
			return false;

		return true;
	}

	bool operator != (const Account &a)
	{
		if (pin == a.pin && firstName == a.firstName && lastName == a.lastName)
			return false;

		return true;
	}
};
Last edited on
Topic archived. No new replies allowed.