0

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!

Blanko
  • 684
  • 8
  • 26
aceaxer
  • 17
  • 3
  • What have you tried? Have you tried putting your line into a stringstream? – Alan Birtles Dec 03 '19 at 07:30
  • Regarding `for (size_t i = 0; i <= 4; i++)`, I believe they want you to use a `std::vector` and something like `while (...)`. Also see [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/q/5605125/608639). – jww Dec 03 '19 at 07:40
  • The problem is, how you get rid of those characters before the numbers, right? Do they hold any meaing? – churill Dec 03 '19 at 07:41

2 Answers2

1

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.

Sumudu
  • 5,705
  • 14
  • 49
  • 82
1

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;
}
Girspoon
  • 96
  • 5
  • The only question I have is that the withdrawals and the deposits are not being separate properly I will play around with it but got any tips on that I see you implemented a sorting system but it seems to be over looked by the compiler. – aceaxer Dec 03 '19 at 09:18
  • I added another for loop to print out the withdrawals array and it all seems to be correct on my end. Could you update the main post with what's happening? – Girspoon Dec 03 '19 at 10:05