Чтение файла CSV с использованием 2d массива - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь прочитать файл CSV, используя 2d массив, но есть проблема с чтением.Первая ячейка файла пропускается, а затем продолжает читать все.Я не понимаю, почему он не читает первую ячейку.

#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();    
}

1 Ответ

0 голосов
/ 05 декабря 2018

Измените это:

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

на это:

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

Кроме того, удалите это getline(jobfile,job[i][j],',');, так как вы пропустите строку таким образом.Когда вы вызвали getline в состоянии цикла while, он уже прочитал строку (в результате теперь вы должны сохранить эту строку. Затем, когда условие цикла while оценивается снова, следующая строка будет прочитана).


Однако это становится намного сложнее, чем это, поскольку вы arrival будете удерживать один токен за раз, пока он не встретит последний токен текущей строки.В этом случае arrival будет таким: "currentLineLastToken\nnextLineFirstToken".

По этой причине вам нужно специально обработать случай, когда в прибытии содержится символ новой строки, используйте для этого string::find.

Когда найдена новая строка, вы должны разбить эту строку на эту новую строку, чтобы извлечь два задействованных токена.Для этого используйте string::substr.

Более того, вы не должны зацикливаться внутри цикла while с двойным значением for для хранения токена, вы только что прочитали.Используйте двойной цикл for, когда пришло время печатать job, только после выхода из цикла while, который читает файл.

Собрав все вместе, мы получим следующее:

#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();
}

Вывод (для моего пользовательского ввода):

Successfully open file
aa bb cc dd 
bla blu blo ble 
qq ww ee rr
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...