Beginner
Beginner

Reputation: 27

Read csv file using 2d array

I'm trying to read a CSV file using 2d array but there's a problem with the reading. The first cell of the file is skipped and then continues read all. I don't understand why it doesn't read the first cell.

#include<iostream>
#include<fstream>
#include<cstring>
#include<string>
#include<sstream>
using namespace std;

int main()
{
  string arrival,job[3][4];
  ifstream jobfile("myfile.csv");
  std::string fileCommand;

  if(jobfile.is_open())
  {
      cout << "Successfully open file"<<endl;

      while(getline(jobfile,arrival,','))
      {
        for(int i=1;i < 4;i++) //i = no. of job
        {
            for(int j=0; j<4; j++) // j = no. of processes
            {
                getline(jobfile,job[i][j],',');
                cout << "Job[" << i << "]P[" << j << "]: "<< job[i][j]<< endl;
            }

        }//end for
      }//end while
  }//end if for jobfile open
  jobfile.close();    
}

Upvotes: 1

Views: 745

Answers (1)

gsamaras
gsamaras

Reputation: 73366

Change this:

for(int i=1;i < 3;i++)

to this:

for(int i=0;i < 3;i++)

Also, remove this getline(jobfile,job[i][j],',');, since you skip a line that way. When you called getline in the condition of the while loop, it already read a line (as a result, now, you have to store that line. Then, when the condition of the while loop is evaluated again, the next line will be read).


However, it gets much more complicated than this, since you arrival will hold one token at a time, until it meets the last token of the current line. In that case, arrival will be this: "currentLineLastToken\nnextLineFirstToken".

For that reason, you need to specially handle the case that arrival contains a newline, use string::find for this.

When a newline is found, you should split that string to that newline, in order to extract the two tokens involved. Use string::substr for this.

Moreover, you shouldn't loop inside the while loop with a double for to store the token, you just read. Use a double for loop, when it is time to print job, only after exiting the while loop that read the file.

Putting everything together, we get this:

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

int main()
{
  string arrival,job[3][4];
  ifstream jobfile("myfile.csv");
  std::string fileCommand;

  if(jobfile.is_open())
  {
      cout << "Successfully open file"<<endl;

      int i = 0, j = 0;
      while(getline(jobfile,arrival,','))
      {
        //cout << "|" << arrival << "|" << endl;
        size_t found = arrival.find("\n");
        if (found != std::string::npos) // if newline was found
        {
                string lastToken = arrival.substr(0, found);
                string nextLineFirstTOken = arrival.substr(found + 1);
                job[i++][j] = lastToken;
                j = 0;
                if(nextLineFirstTOken != "\n") // when you read the last token of the last line
                        job[i][j++] = nextLineFirstTOken;
        }
        else
        {
                job[i][j++] = arrival;
        }

      }//end while

      for(int i = 0; i < 3; ++i)
      {
        for(int j = 0; j < 4; ++j)
        {
                cout << job[i][j] << " ";
        }
        cout << endl;
      }

  }//end if for jobfile open
  jobfile.close();
}

Output (for my custom input):

Successfully open file
aa bb cc dd 
bla blu blo ble 
qq ww ee rr

Upvotes: 1

Related Questions