basics uses of vectors for an A/R basic program
I need help in writing a program using vectors, I haven't wrote any programs in over a yrs and even then I was struggling.
I need the program to read from two files
file (1) is a master file in ascending order by customer number (4 digits long), it also contains a 20 character customer name and a balance due..
(ex. 1001 "NAME" Balance)
this is that file looks...
Code:
1001 Jack 305.78
2002 Roofing 414.67
3003 Showers 210.44
4004 Handyman 140.63
5005 repairs 490.12
6006 Mechanic 53.34
7007 Appliance 180.77
file (2) is a transaction file that contains records of each transaction.
each records start with a character "O" or "P"
if it's in "O" for the order.. containing item ordered quantity ordered plus cost of the item (I need to multiply to get the cost)
ex. (O "Customer#" "Transaction#" "description" "quantity" "price")
"P" contains the amount of payment
ex. ( P "customer#" "transaction#" "paymentAmout")
this is how that file looks...
Code:
O 1001 5493 toilets 8 56
P 1001 5494 250
P 1001 9286 54
O 1001 8884 Pipe 2 350
P 1001 9960 180
O 2002 8924 Cutter 1 2195
P 2002 1115 1034
P 2002 9182 404
O 2002 801 Shaft 1 450
P 2002 8193 555
O 3003 1734 Shower 1 621
P 3003 1112 542
P 3003 1022 324
P 3003 4401 197
P 3003 6732 32
O 4004 7731 Panels 20 9
P 4004 3215 185
P 4004 3034 52
O 4004 3218 Cement 20 12
P 4004 1888 179
O 5005 9995 Unit 1 2259
P 5005 1918 259
P 5005 1920 575
P 5005 1925 503
P 5005 1928 317
O 6006 2020 Tools 2 115
O 6006 2122 Trays 3 60
P 6006 1101 59
P 6006 1020 107
P 0006 1033 33
O 7007 2455 Dishwasher 31
O 7007 2456 Panel 2 151
P 7007 9854 81
P 7007 5515 45
P 7007 6222 231
I need the program to read in records one at a time from the two files and use the transaction file to update the master file. process all transaction records for each master record before going on to the next record. if the transactions contain an "O" in column 1, calculate the order amount and add it to the balance due. if the record contains a "P" in column 1, subtract the payment from the balance due. keep a running total of the A?R Balance of ABC Company
After processing a master record and all it's transaction the program should prepare an invoice for each customer which lists the customer name, number, previous balance.
the output should look like this
CUSTOMER NAME CUSTOMER NUMBER
PREVIOUS BALANCE $XXX.XX
TRANSACTION # ITEM ORDERED $ORDER AMOUNT
TRANSACTION # ITEM ORDERED $ORDER AMOUNT
TRANSACTION # PAYMENT $ORDER AMOUNT
TRANSACTION # ITEM ORDERED $ORDER AMOUNT
BALANCE DUE $XXX.XX
I need someone who has a patients to walk me through how to write this program.
I don't have much coding all I have is basically reading in the two files.. anything else my mind is blank.. This is what I have so far
Code:
#include<iostream>
#include<iomanip>
#include<string>
#include<cstring>
#include<fstream>
#include<vector>
struct master
{
int custNumber;
std::string custName;
double balance;
};
struct transactions
{
char transactionType;
int custNumber;
int transNumber;
std::string item;
int quantity;
double price;
double amountPaid;
};
using namespace std;
int main()
{
{
vector<master>masterData;
vector<transactions>transactionData;
ifstream masterfile("master list.txt", ios::out | ios::in | ios::binary);
ifstream transactionfile("transaction.txt", ios::out | ios::in | ios::binary);
while (masterfile)
{
master m;
masterfile>>m.custNumber>>m.custName>>m.balance;
masterData;
if(masterfile)
{
masterData.push_back(m);
}
}
while (transactionfile)
{
transactions n;
transactionfile>>n.custNumber>>n.transNumber>>n.item>>n.quantity>>n.price>>n.amountPaid;
transactionData;
if(transactionfile)
{
transactionData.push_back(n);
}
}
Thank you in advance for all your help, I know it's a lot..
Re: basics uses of vectors for an A/R basic program
The code is overall good, but there are a few issues. Let's start from the top:
Code:
ifstream masterfile("master list.txt", ios::out | ios::in | ios::binary);
You want to read from this file, and you already have an ifstream. Just do "ifstream masterfile("master list.txt", ios::binary);"
This will not initialize your struct. You can either give a constructor, or explicitly initialize it at call site with "master m = {};". Note that both are mutually exclusive. If your project does C++11, then you can do "master m{};" which will always work. (Or if you follow the AAA (Almost Always Auto) rule, then "auto m = master{};")
Code:
while (masterfile)
{
master m;
masterfile>>m.custNumber>>m.custName>>m.balance;
This is kind of very very detail oriented, but what will usually happen is that a stream might have no characters left in it, but the "end" has not been reached yet (you need to attempt to read past the last character for a stream to end). Rather, what you want to do is test that the stream is still good *after* you read from it. In pratical terms, it means you want to do this:
Code:
master m;
while (masterfile>>m.custNumber>>m.custName>>m.balance)
{
masterData.push_back(m);
}
Code:
transactionfile>>n.custNumber>>n.transNumber>>n.item>>n.quantity>>n.price>>n.amountPaid;
This will not work, as (for starters) it does not read the transaction type, making the rest of the reads error out, and second, not every transaction has the info you want.
To remedy this, you usually want to read an entire line at once, and then process that line. stringstream is a class that wraps a string into a stream allowing you to read from the string as if it were a file, but only 1 line at once. Then, you read the first few fields, and conditionally read the rest:
Code:
string trasactionString;
while (getline(transactionfile, trasactionString))
{
istringstream iss(trasactionString);
transactions n = {};
if (!iss >> n.transactionType >> n.custNumber >> n.transNumber) {
continue;
}
if (n.transactionType == 'O')
{
iss >> n.item >> n.quantity >> n.price;
}
if else (n.transactionType == 'O')
{
iss >> n.amountPaid;
}
else
{
continue;
}
if (iss)
{
transactionData.push_back(n);
}
}
Note that this "getline" approach is often the recommended approach to reading a file, even if all the lines are the same: It is more robust in the sense that you really are tacking into account the structure or your file. If you simply read your file field by field, you are completely ignoring the layout of your file.
Once you have corrected these issues, I suggest you add the code to simply print what you just read, and make sure you are reading what you expected.
From there, the next logical step is to "map" the transactions to your masters. "map" will do the job for that pretty well. You can either go for a "multimap<key, value>" (one key maps to several values) or a "map<key, container<value>>". They are both conceptually the same thing, but IMO, the second is easier to use *and* gives you finer control on how you store your values.
***The following is a bit more advanced, and may or may not make things easier for you. Feel free to ignore if you don't feel comfortable with it.***
Instead of manipulating the "master" and "transaction" objects directly, is to simply manipulate their "number". Then you can have a map of transaction number to customer number. From the numbers, you can lookup the actual customers and transactions.
The advantages here first that it avoid duplicating objects, which helps guarantee your data integrity should you make any changes to, say, a customer name. The second is that you won't need to write a comparison operator or hash function for your customer/transactions, as you will be manipulating them by number anyways.
Re: basics uses of vectors for an A/R basic program
Quote:
You want to read from this file, and you already have an ifstream. Just do "ifstream masterfile("master list.txt", ios::binary);"
The files from which to read are text so the mode should be text rather than binary. ie
Code:
ifstream masterfile("master list.txt");
Re: basics uses of vectors for an A/R basic program
Another way of obtaining the data from the files could be
Code:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const char TORD = 'O';
const char TPAY = 'P';
struct master
{
master() : custNumber(0), custName(""), balance(0.0) {}
int custNumber;
string custName;
double balance;
};
struct transactions
{
struct Torder
{
Torder() : desc(""), quantity(0), price(0.0) {}
string desc;
int quantity;
double price;
};
struct Tpayment
{
Tpayment() : payment(0.0) {}
double payment;
};
transactions() : transactionType(' '), custNumber(0), transNumber(0), pay(), order() {}
char transactionType;
int custNumber;
int transNumber;
Tpayment pay;
Torder order;
};
istream& operator >>(istream& is, master& m)
{
return (is >> m.custNumber >> m.custName >> m.balance);
}
ostream& operator <<(ostream& os, const master& ms)
{
return (os << ms.custNumber << " " << ms.custName << " " << ms.balance);
}
istream& operator >>(istream& is, transactions& t)
{
if (is >> t.transactionType >> t.custNumber >> t.transNumber)
switch (t.transactionType) {
case TORD:
is >> t.order.desc >> t.order.quantity >> t.order.price;
break;
case TPAY:
is >> t.pay.payment;
break;
default:
//deal with bad transaction type
break;
}
return is;
}
ostream& operator <<(ostream& os, const transactions& ts)
{
os << ts.transNumber << " " << ts.transactionType << " " << ts.custNumber << " ";
switch (ts.transactionType) {
case TORD:
os << ts.order.desc << " " << ts.order.price << " " << ts.order.quantity;
break;
case TPAY:
os << ts.pay.payment;
break;
default:
os << "bad type" << endl;
break;
}
return os;
}
int main()
{
const string mfn = "master.txt";
const string tfn = "trans.txt";
ifstream mfs(mfn);
ifstream tfs(tfn);
if (!mfs.is_open()) {
cerr << "Cannot open master file " << mfn << endl;
return 1;
}
if (!tfs.is_open()) {
cerr << "Cannot open trans file " << tfn << endl;
return 2;
}
vector<master> vm;
master ms;
while (mfs >> ms)
vm.push_back(ms);
vector<transactions> vt;
transactions ts;
while (tfs >> ts)
vt.push_back(ts);
for (const auto& m : vm)
cout << m << endl;
for (const auto& t : vt)
cout << t << endl;
}
Note that in the sample transactions in post #1 there is a bad order transaction missing a quantity.
Re: basics uses of vectors for an A/R basic program
Thank you guys so much for taking time to post this, when trying to run this program I'm getting an error
Quote:
"error: no matching function for call to 'std::basic_ifstream<char>::basic_ifstream(const string&)'|
for . what does that mean and how can I fix it?
Re: basics uses of vectors for an A/R basic program
What compiler are you using? The posted code assumes c++11.
Re: basics uses of vectors for an A/R basic program
I'm using Code::Blocks. I know that it's C++ , but I'm not sure if it's C++11.. can you recommend a good compiler that's c++ 11 ?
Re: basics uses of vectors for an A/R basic program
code::blocks uses GNU GCC Compiler
Re: basics uses of vectors for an A/R basic program
I figured out how to add c++11 to codeblocks.. I will run it later this afternoon.. thank you as always for your help
Re: basics uses of vectors for an A/R basic program
I've updated code::blocks in order to work with C++11, everything seems to work fine, the problem is the output reads back what's in the master file only..
The output should look something like this
Customer name Customer Number
Previous Balance $XXX.XX
Transaction # Item Ordered $ Order Amount
Transaction # Item Ordered $ Order Amount
Transaction # Payment $ Payment Amount
Transaction # Item Ordered $ Order Amount
Balance Due $XXX.XX
Thank you so much
Re: basics uses of vectors for an A/R basic program
Quote:
Originally Posted by
gwiz01
I've updated code::blocks in order to work with C++11, everything seems to work fine, the problem is the output reads back what's in the master file only..
The output should look something like this
Customer name Customer Number
Previous Balance $XXX.XX
Transaction # Item Ordered $ Order Amount
Transaction # Item Ordered $ Order Amount
Transaction # Payment $ Payment Amount
Transaction # Item Ordered $ Order Amount
Balance Due $XXX.XX
Thank you so much
Sounds like you need to write the code that does that? What do you have so far?
Re: basics uses of vectors for an A/R basic program
Quote:
the problem is the output reads back what's in the master file only..
No, that's not a problem - that's by design! I only gave an alternative way of reading the files from that which you provided in post #1. I didn't provide the rest of the code. You'll need to do that. Once you have then if post your additional code we'll provide further advice and guidance.
Re: basics uses of vectors for an A/R basic program
This is what I have so far, I know I still have so much to learn.
Code:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const char TORD = 'O';
const char TPAY = 'P';
struct master
{
master() : custNumber(0), custName(""), balance(0.0) {}
int custNumber;
string custName;
double balance;
};
struct transactions
{
struct Torder
{
Torder() : desc(""), quantity(0), price(0.0) {}
string desc;
int quantity;
double price;
};
struct Tpayment
{
Tpayment() : payment(0.0) {}
double payment;
};
transactions() : transactionType(' '), custNumber(0), transNumber(0), pay(), order() {}
char transactionType;
int custNumber;
int transNumber;
Tpayment pay;
Torder order;
};
istream& operator >>(istream& is, master& m)
{
return (is >> m.custNumber >> m.custName >> m.balance);
}
ostream& operator <<(ostream& os, const master& ms)
{
return (os << ms.custNumber << " " << ms.custName << " " << ms.balance);
}
istream& operator >>(istream& is, transactions& t)
{
if (is >> t.transactionType >> t.custNumber >> t.transNumber)
switch (t.transactionType) {
case TORD:
is >> t.order.desc >> t.order.quantity >> t.order.price;
break;
case TPAY:
is >> t.pay.payment;
break;
default:
//deal with bad transaction type
break;
}
return is;
}
ostream& operator <<(ostream& os, const transactions& ts)
{
os << ts.transNumber << " " << ts.transactionType << " " << ts.custNumber << " ";
switch (ts.transactionType) {
case TORD:
os << ts.order.desc << " " << ts.order.price << " " << ts.order.quantity;
break;
case TPAY:
os << ts.pay.payment;
break;
default:
os << "bad type" << endl;
break;
}
return os;
}
void order_Balance(double&, double&); //add two functions
void payment_Balance(double&, double&);
int main()
{
const string mfn = "master.txt";
const string tfn = "trans.txt";
ifstream mfs(mfn);
ifstream tfs(tfn);
if (!mfs.is_open()) {
cerr << "Cannot open master file " << mfn << endl;
return 1;
}
if (!tfs.is_open()) {
cerr << "Cannot open trans file " << tfn << endl;
return 2;
}
vector<master> vm;
master ms;
while (mfs >> ms)
vm.push_back(ms);
vector<transactions> vt;
transactions ts;
while (tfs >> ts)
vt.push_back(ts);
for (const auto& m : vm)
cout << m << endl;
for (const auto& t : vt)
cout << t << endl;
cout<<master.custName<<"\t"<<master.custNumber<<endl<<endl; //my coding starts here
cout<<"\t\t\t"<<master.balance<<endl<<endl;
for(int 1=0; i<vm.size(); i++)
{
while(TORD=='O')
{
double total;
total=Torder.price[i]*Torder.quantity[i];
cout<<transactions.transNumber[i]<<"t"<<Torder.desc[i]<<"\t$"<<total<<endl;
order_balance(total, master.balance);
}
while(TPAY=='P')
{
cout<<transactions.TransNumber[i]<<Tpayment.Tpayment[i]<<"\t$"<<Tpayment.payment[i]<<endl;
payment_Balance(Tpayment.Tpayment[i],new_Balance)
}
cout<<"\t\t\tBalance Due"<<"\t$"<<New_Balance;
}
}
void order_Balance(double& order, double& previous)
{
order + previous
}
void payment_Balance(double&order, double& previous)
{
order - previous
}
Thanks again for your time.
Re: basics uses of vectors for an A/R basic program
Please make sure your code is at least properly formatted/indented when asking for a review. You main is not even closed.
Code:
cout<<master.custName<<"\t"<<master.custNumber<<endl<<endl; //my coding starts here
Master is a struct name, not an instance. Sounds like you wanted that piece of code to be inside your loop? And then you can change "master" with "vm[i]".
TORD is a constant. This will always be true, you aren't actually testing anything.
Code:
Torder.price[i]*Torder.quantity[i];
Torder is a struct name. You probably want this code inside a loop that iterates on transactions. You probably want to test single elements in vt. Also, don't forget to test that the transaction actually belongs to the correct master.
Code:
void order_Balance(double& order, double& previous)
{
order + previous
}
void payment_Balance(double&order, double& previous)
{
order - previous
}
These are no-op. You are not modifying nor returning anything.
Re: basics uses of vectors for an A/R basic program
Sorry I wasn't able to respond earlier, and I am grateful for all the help you guys are giving me. I've made most of the changes that you suggested but as you probably guessed I'm still having issues with my program.
One major problem I'm having it creating an instance from the struct Torder
Code:
while(TORD)
{
Torder Torders;
double total;
total=Torders.price[i]*Torders.quantity[i];
cout<<transactions.transNumber[i]<<"t"<<Torders.desc[i]<<"\t$"<<total<<endl;
order_balance(total, ms.balance);
}
The program so far looks like this. Thank you so much for taking time in helping me, for you guy it's probably real simple, for me it's everything.. thank you
Code:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const char TORD = 'O';
const char TPAY = 'P';
struct master
{
master() : custNumber(0), custName(""), balance(0.0) {}
int custNumber;
string custName;
double balance;
};
struct transactions
{
struct Torder
{
Torder() : desc(""), quantity(0), price(0.0) {}
string desc;
int quantity;
double price;
};
struct Tpayment
{
Tpayment() : payment(0.0) {}
double payment;
};
transactions() : transactionType(' '), custNumber(0), transNumber(0), pay(), order() {}
char transactionType;
int custNumber;
int transNumber;
Tpayment pay;
Torder order;
};
istream& operator >>(istream& is, master& m)
{
return (is >> m.custNumber >> m.custName >> m.balance);
}
ostream& operator <<(ostream& os, const master& ms)
{
return (os << ms.custNumber << " " << ms.custName << " " << ms.balance);
}
istream& operator >>(istream& is, transactions& t)
{
if (is >> t.transactionType >> t.custNumber >> t.transNumber)
switch (t.transactionType) {
case TORD:
is >> t.order.desc >> t.order.quantity >> t.order.price;
break;
case TPAY:
is >> t.pay.payment;
break;
default:
//deal with bad transaction type
break;
}
return is;
}
ostream& operator <<(ostream& os, const transactions& ts)
{
os << ts.transNumber << " " << ts.transactionType << " " << ts.custNumber << " ";
switch (ts.transactionType) {
case TORD:
os << ts.order.desc << " " << ts.order.price << " " << ts.order.quantity;
break;
case TPAY:
os << ts.pay.payment;
break;
default:
os << "bad type" << endl;
break;
}
return os;
}
void order_Balance(double&, double&); //add two functions
void payment_Balance(double&, double&);
int main()
{
const string mfn = "master.txt";
const string tfn = "trans.txt";
ifstream mfs(mfn);
ifstream tfs(tfn);
if (!mfs.is_open())
{
cerr << "Cannot open master file " << mfn << endl;
return 1;
}
if (!tfs.is_open())
{
cerr << "Cannot open trans file " << tfn << endl;
return 2;
}
vector<master> vm;
master ms;
while (mfs >> ms)
vm.push_back(ms);
vector<transactions> vt;
transactions ts;
while (tfs >> ts)
vt.push_back(ts);
for (const auto& m : vm)
cout << m << endl;
for (const auto& t : vt)
cout << t << endl;
cout<<ms.custName<<"\t"<<ms.custNumber<<endl<<endl;
cout<<"\t\t\t"<<ms.balance<<endl<<endl;
for(int i=0; i<vm.size(); i++)
{
while(TORD)
{
Torder Torders;
double total;
total=Torders.price[i]*Torders.quantity[i];
cout<<transactions.transNumber[i]<<"t"<<Torders.desc[i]<<"\t$"<<total<<endl;
order_balance(total, ms.balance);
}
while(TPAY)
{
Tpayment Tpayments;
cout<<transactions.TransNumber[i]<<Tpayments.Tpayment[i]<<"\t$"<<Tpayments.payment[i]<<endl;
payment_Balance(Tpayments.Tpayment[i],new_Balance)
}
cout<<"\t\t\tBalance Due"<<"\t$"<<New_Balance;
}
}
void order_Balance(double& order, double& previous)
{
double x;
x=order + previous;
return x;
}
void payment_Balance(double&order, double& previous)
{
double y;
y=previous - order;
return y;
}
I apologize for the indentation, I realize it's still not correctly formatted