c++arraysgetline

How to split using getline() in c++


My Input file,

 AMZN~Amazon.Com Inc~1402.05~+24.10~+1.75%~4854900~6806813~01/26/18~1523
 AAPL~Apple Inc~171.51~+0.40~+0.23%~39128000~6710843~01/26/18~1224`

My code,

 #include <iostream>
 #include <fstream>
 #include <string>
 #include <iomanip>
 using namespace std;

 int main()
 {
    string line1[30];
    string line2[30];
    ifstream myfile("sp03HWstock.txt");
    int a = 0;

    if(!myfile) 
    {
    cout<<"Error opening output file"<<endl;
    system("pause");
    return -1;
    }
    cout
       << left
       << setw(10)
       << "Stock Name              "
       << left
       << setw(5)
       << " Value  "
       << left
       << setw(8)
       << "Quantity   "
       << left
       << setw(5)
       << "   Total Worth  "
       << endl;
  while(!myfile.eof())
  {
   getline(myfile,line1[a],'~');

    cout
        << left
        << setw(10);


   cout<<  line1[a];
  }
}

Desired output,

Stock Name               Value  Quantity      Total Worth  
Amazon.Com Inc          1402.05 +24.10        6806813   
Apple Inc               171.51  +0.23%        6710843

The output I got,

Stock Name               Value  Quantity      Total Worth  
AMZN     Amazon.Com Inc1402.05   +24.10    +1.75%    4854900   6806813   01/26/18  1523
AAPLApple Inc 171.51    +0.40     +0.23%    39128000  6710843   01/26/18  1224`

I am using getline(myfile,line1[a],'~'); to split by '~' and I am not able to perform further split on it. Can some one please help me to figure it out. Thanks!!


Solution

  • A basic approach is to first give yourself more flexibility and less hard-coding related to the columns. Something like this:

    const int MAX_COLUMNS = 6;
    
    struct {
        const char* name;
        int width;
    } columns[MAX_COLUMNS] = {
        { NULL },                 // Don't care
        { "Stock Name", 16 },
        { "Value", 10 },
        { "Quantity", 10 },
        { NULL },                 // Don't care
        { "Total Worth", 12 },
    };
    

    Then, you can easily output your column headers as follows:

        // Print column headings
        cout << left;
        for (int i = 0; i < MAX_COLUMNS; i++)
        {
            if (columns[i].name)
            {
                cout << setw(columns[i].width) << columns[i].name;
            }
        }
        cout << endl;
    

    For the actual data, a convenient way to handle it is to first read an entire line and then use a std::istringstream to split the contents of that line:

        // Read and process lines
        string line;
        while (getline(myfile, line))
        {
            istringstream iss(line);
            string item;
            int count = 0;
            while (count < MAX_COLUMNS && getline(iss, item, '~'))
            {
                if (columns[count].name)
                {
                    cout << setw(columns[count].width) << item;
                }
                ++count;
            }
            cout << endl;
        }
    

    Output:

    Stock Name      Value     Quantity  Total Worth 
    Amazon.Com Inc  1402.05   +24.10    4854900     
    Apple Inc       171.51    +0.40     39128000    
    

    If you need to display your columns in a different order, then you can first split the values into a vector<string> and then output that in whatever order you want.