Output issue reading in 2 files

Hello! I am reading 2 files into a program, a client list and transaction file. When the Client ID's match, I need to increment the total on the Client list by the amount on the Transaction file. If there is a transaction on the Transaction file that does not match to the Client list, I need to write, "Error - Client not on Master File". Everything is working fine except for the Error records. Every record is getting the error message except for the record on the Client list that isn't on the treansaction file. I have tried multiple things and usually end up in a never ending loop. Here is the data:

Client file:

5 Mike Smith 2098.72
6 Sue Nathan 1234.32
100 Bobby Jones 519.69
125 Sally Mayer 345.74
200 Danny Glover 5623.18

Transaction File:

1 568.34
5 345.10
6 1012.43
17 2045.12
100 1231.00
101 167.39
125 5239.67

1, 17 and 101 should be the only recs on the Error file. Any help is deeply appreciated!


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
  #include <iostream>
#include <fstream>
#include <string>

using namespace std;
int main()
{

	 ifstream inFile1;
         ifstream inFile2;
         ofstream outFile1;
         ofstream outFile2;
         float mClientNumber, tClientNumber;
	 float mtotalClientCost, titemClientCost;
	 string mClientfName, mClientlName;
		 
		 
//     output "Master File Updating Starting"
		cout << "Master File Updating Starting..." << endl;
//     open files
	 inFile1.open("Master.txt");
	 inFile2.open("Transaction.txt");
         outFile1.open("newMaster.txt");
         outFile2.open("errorReport.txt");
     
//     read in input data
	 inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
	 inFile2 >> tClientNumber >> titemClientCost;
  

while (!inFile2.eof())
{

if(!inFile1.eof())
{
if (mClientNumber == tClientNumber)
{
	mtotalClientCost = mtotalClientCost + titemClientCost;
	outFile1 << mClientNumber << "  " << mClientfName << "  " << mClientlName << "  " << mtotalClientCost << endl;	
	inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
	cout << "Client ID: " << tClientNumber << " in both Files.";
}
//			else if (inFile1.eof()) 
else if(tClientNumber != mClientNumber) 
{
	outFile2 << "Error Client ID: " << tClientNumber << " not in Master File." << endl;
	inFile2 >> tClientNumber >> titemClientCost;
	cout << "Error Client ID: " << tClientNumber << " Not in Master File.";
}
}

}
while (!inFile1.eof())
{
        outFile1 << mClientNumber << "  " << mClientfName << "  " << mClientlName << "  " << mtotalClientCost << endl;
        inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
}

//    close files 
	inFile1.close();   
	inFile2.close();  
	outFile1.close();  
	outFile2.close(); 
     
//     output "Master File Updating Complete"
	cout << "Master File Updating Complete " << endl;
    return 0;
}
Last edited on
Are you sure your files are all opening correctly? You really should check.

You've told us a little of what you want the program to do, but you haven't told us what the program is actually doing. Please describe the exact problem you are experiencing.

my apologies.

I have a Master Client list with Client ID, Client Name, and amount spent. The Tranaction file has the Client ID and the amount of current transactions. I need to match the 2 files. If there is a match by Client ID, I need to add the amount of the current transaction to the amount spent total and write out the record. If there is a record on the Master Client list that is not on the transaction file, I just need to write out the recorda as is. If there are Client ID's on the Transaction file which are not on the Master Client list, I need to write out "Error - Client ID "#" not in Master File.

Everything is working fine except for the Error file.
Have you studied structures/class and std::vector yet?

This would be much easier to do if you were to initially read the two input files into a std::vector of a client and transaction structure/class.

You need to compare each transaction id against every client id to make sure the transaction has a correct id number.

Also your id "number" should probably be either a string (recommended) or an int since comparing floating point numbers for equality is hazardous.

no, sadly we are not that far into our studies. I did do some research on this, but would like to keep the program in the scope of what we have learned so far. This is an introduction to programming class.

I did as you suggested and changed the client id to a string. Thank you for that input!

So then what have you studied so far?

IMO, classes/structures and std::vector along with std::string should be introduced very early in an intro course.

Have you studied arrays? Dynamic memory allocation?

Without std::vector/arrays you need to read at least one of the files over and over, which has probably also not been covered, as re-reading a file is a little more advanced.

What about functions have they been covered?


Last edited on
My apologies for the lack of response. I am taking 5 classes this summer and working nearly full time. We have studied structure of course, and are just into the chapters on arrays. I thought my question may have a simple solution and come to find out it did. I was missing one line of code.......


if (mClientNumber == tClientNumber)
{
mtotalClientCost = mtotalClientCost + titemClientCost;
outFile1 << mClientNumber << " " << mClientfName << " " << mClientlName << " " << mtotalClientCost << endl;
inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
inFile2 >> tClientNumber >> titemClientCost; -- this was missing
cout << "Client ID: " << tClientNumber << " in both Files.";
}

my teacher's pseudocode was missing this.

anyway, thank you for your time, it is appreciated. I kind of like figuring these things out for myself as it is always a learning experience. With my lack of time it is difficult sometimes.
Last edited on
We have studied structure of course, and are just into the chapters on arrays.

Then you really should take advantage of both of these concepts, along with functions, since they will make the program logic much easier to follow.
Are you sure this is all correct? The code won't work if there are multiple transactions for the same client, or if are no transactions for a client. It also assumes that the client IDs are in order in both files, but that's probably a given in the assignment.
yes, once I was sure I was getting proper output, I added the read/writes. here is the updated code:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
int main()
{

ifstream inFile1;
ifstream inFile2;
ofstream outFile1;
string mClientNumber;
string tClientNumber;
float mtotalClientCost, titemClientCost;
string mClientfName, mClientlName;


// output "Master File Updating Starting"
cout << "Master File Updating Starting..." << endl;
// open files
inFile1.open("Master.txt");
inFile2.open("Transaction.txt");
outFile1.open("newMaster.txt");

// read in input data
inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
inFile2 >> tClientNumber >> titemClientCost;


while (!inFile2.eof())
{


while ((!inFile1.eof()) and (mClientNumber < tClientNumber))
{
outFile1 << "Error Client ID: " << tClientNumber << " not in Master File." << endl;
inFile2 >> tClientNumber >> titemClientCost;
}
if (inFile1.eof())
{
outFile1 << "Error Client ID: " << tClientNumber << " not in Master File." << endl;
inFile2 >> tClientNumber >> titemClientCost;
}
else if (mClientNumber == tClientNumber)
{
mtotalClientCost = mtotalClientCost + titemClientCost;
outFile1 << mClientNumber << " " << mClientfName << " " << mClientlName << " " << mtotalClientCost << endl;
inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
inFile2 >> tClientNumber >> titemClientCost;
}
else if (mClientNumber > tClientNumber)
{
outFile1 << "Error Client ID: " << tClientNumber << " not in Master File." << endl;
inFile2 >> tClientNumber >> titemClientCost;
}
}

while (!inFile1.eof())
{
outFile1 << mClientNumber << " " << mClientfName << " " << mClientlName << " " << mtotalClientCost << endl;
inFile1 >> mClientNumber >> mClientfName >> mClientlName >> mtotalClientCost;
}

// close files
inFile1.close();
inFile2.close();
outFile1.close();

// output "Master File Updating Complete"
cout << "Master File Updating Complete " << endl;
return 0;
}
code tags
@OP

Looks like it works.

As a suggestion, checkout <cstdio> functionality and after the run is complete, rename your 'master' to 'oldmaster' and rename 'newmaster' to 'master'.

Depending, delete 'oldmaster' as a complete cleanup.

http://www.cplusplus.com/reference/cstdio/rename/
http://www.cplusplus.com/reference/cstdio/remove/
Thank you! these are excellent suggestions and very good to learn. In real life, I can see the clean up being very important, so this is a great thing to know. In class, we get penalized greatly if we do not follow the teachers pseudocode to the tee.
It's not about copying this but this might be useful.

There's a problem with it in principle though. In a production system probably beyond the scope of this, you need a way to ensure that item costs already recorded aren't continually added to the total - a bit unfair on the customer. A 'already_totalled' flag for checking on the transaction line would do it.

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 <iostream>
#include <fstream>
#include <string>

int main()
{
    std::cout << "Master File Updating Starting...\n";
    
    std::ifstream client_file ("clients.txt");
    if (!client_file.is_open() )
    {
        std::cout << "Unable to open client file";
        return -99;
    }
    
    std::ifstream transaction_file ("transactions.txt");
    if (!transaction_file.is_open() )
    {
        std::cout << "Unable to open transaction file";
        return -98;
    }
    
    std::ofstream temp_file;
    temp_file.open("temp.txt");
    
    std::ofstream error_file;
    error_file.open("client_error.txt");
    
    int c_clientNo;
    int t_clientNo;
    
    double total_cost{0}, item_cost{0};
    std::string first_name, last_name;
    bool found{false};
    
    while (transaction_file >> t_clientNo >> total_cost)
    {
        // START AT THE BEGINNING
        client_file.clear();
        client_file.seekg(0, std::ios::beg);
        
        found = false;
        
        // CHECK AGAINST CLIENT LIST
        while(client_file >> c_clientNo >> first_name >> last_name >> item_cost)
        {
            if(t_clientNo == c_clientNo)
            {
                temp_file
                << c_clientNo << ' ' << first_name << ' ' << last_name << ' '
                << total_cost + item_cost << '\n';
                
                found = true;
            }
        }
        if (!found)
            error_file << t_clientNo << " Not found\n";
    }
    
    client_file.close();
    transaction_file.close();
    temp_file.close();
    error_file.close();
    
    // CLEANUP
    if( remove( "clients.txt" ) != 0 )
        perror( "Error deleting file" );
    else
        std::cout << "clients.txt file successfully deleted\n";
    
    if ( rename( "temp.txt" , "clients.txt" ) != 0 )
        perror( "Error renaming file" );
    else
        std::cout << "File successfully renamed\n";
    
    std::cout << "Master File Updating Complete\n";
    
    return 0;
}
Topic archived. No new replies allowed.