Reputation: 17
I need to be able to read in (first number is meant to be id number followed by transactions, making bank statement code, d means deposit, w is withdrawal, numbers after are amount):
123 d45.10 d50.45 d198.56 w45.67
345 w34.00 d4.56 w45.13 d23.23 w23.12
639 d1000.34 d1234.56 w34.33 w345.87 w22.13
890 d345.67 d123.67 d45.99 d45.99 w34.77
666 d66.60 d666.66 d6.66 d66.6 d6666.66
and have it sort into different arrays all stored within a struct. I have tried string stream and various other things i thought of, I'm like medium versed in c++, in the first year class to be specific.
This is the code I have so far, The first set of read ins is working properly but I cannot get the second one to work:
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
using namespace std;
struct PersonAcct {
int acct_num[5];
string name[5];
double acct_bal[5];
};
struct PersonTrans {
int acct_num[5];
double trans[20];
char d_p[20];
};
int main() {
ifstream ifacc("accounts.txt");
PersonAcct p;
if (ifacc.is_open()) {
for (int i = 0; i <= 4; i++) {
ifacc >> p.acct_num[i];
ifacc >> p.name[i];
ifacc >> p.acct_bal[i];
}
}
ifacc.close();
ifstream iftrans;
iftrans.open("transactions.txt");
PersonTrans q;
string line,line2,line3,line4,line5;
if (iftrans.is_open()) {
int counter = 0;
while (getline(iftrans,line)) {
cout << line << endl;
counter++;
}
}
return 0;
}
Any help would be much appreciated! As I said before I am pretty new in retrospect to most of you on here so please be detailed or explain it for someone a bit daft in this subject, as I prob could be considered. I thank you and wish you a happy early holiday season!
Upvotes: 0
Views: 86
Reputation: 96
So I probably implemented it stupidly but here's what I thought you should do. Since the first thing will always be an ID I added that to acct_num;
Next I have a while loop for the line, I create a new string stream (Probably bad form, unsure) using a substring of everything after the first letter. Then I check the first letter of each transaction whether or not its a d or a w and put them into arrays. I had two counters for the w and d arrays. If they were vectors this wouldn't be necessary.
I wasn't sure what your original struct meant so I just created an array for deposits and withdrawals.
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
using namespace std;
struct PersonTrans {
int acct_num[5];
double deposits[20];
double withdrawals[20];
};
int main() {
ifstream iftrans;
iftrans.open("transactions.txt");
PersonTrans q;
if (iftrans.is_open()) {
int i = 0;
int d = 0;
int w = 0;
string line;
while (getline(iftrans,line)) {
stringstream in(line);
string tmp;
int idNumber;
in >> idNumber;
q.acct_num[i] = idNumber;
while(in >> tmp) {
double value;
std::stringstream transaction(tmp.substr(1));
transaction >> value;
if (tmp[0] == 'd'){
q.deposits[d] = value;
d++;
}
else if (tmp[0] == 'w'){
q.withdrawals[w] = value;
w++;
}
}
i++;
}
}
for(int i = 0; i < 20; i++){
cout << q.deposits[i] << endl;
}
return 0;
}
Upvotes: 1
Reputation: 7445
If I understand you correct, you need to parse different words in different lines. You should be able to get this done easily with std::stringstream
.
e.g.
...
iftrans.open("transactions.txt");
if (iftrans.is_open())
{
int counter = 0;
string line;
while (getline(iftrans, line)) // iterate through lines
{
int id;
string word;
stringstream ss(line);
ss >> id; // first word is the ID
while (ss >> word) // iterate though words of current line
{
switch (word[0]) // a word starts with either `w` or `d`
{
case 'w':
{
// remaining characters represent a valid double
double const val = stod(word.substr(1));
// process withdrawal
// ...
break;
}
case 'd':
{
double const val = stod(word.substr(1));
// process deposit
// ...
break;
}
default: break; // error?
}
}
counter++;
}
}
You may need to do additional error handling if the commented assumptions are not guaranteed to be valid always.
Upvotes: 1