1

I have to parse several csv files with the same basic structure and I have to save the values in different matrixes. I'd like to save each table in a single matrix but the problem is that I have some issues with the endline character. I tried to use the getlinefunction but I can't terminate the while cycle when the table is parsed.

I use this code:

// MMDS.cpp : definisce il punto di ingresso dell'applicazione console.
//

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

using namespace std;

int i = 0, j = 0 , z=0;

int main()
{
    ifstream file("I_30_2_02_02_1.csv"); // declare file stream
    string value;
    string intvalue;
    string check;
    int jobs;
    int machines;
    int resources;
    vector<string> JobTime;
    vector<string> MachineId;
    vector<string> ProcTime; //archiviato come JobId MachineId ProcTime

    //prime tre righe
    getline(file, value, ';'); // #jobs
    getline(file, intvalue, '\n');
    jobs = stoi(intvalue);
    cout << "Jobs: " <<jobs << "\n";

    getline(file, value, ';'); //#machines
    getline(file, intvalue, '\n');
    machines = stoi(intvalue);
    cout << "Machines: " << machines << "\n";

    getline(file, value, ';'); //#resources
    getline(file, intvalue, '\n');
    resources = stoi(intvalue);
    cout << "Resources: " << resources << "\n";

    //scritte inutili
    getline(file, value, ';');
    cout << value << " ";
    getline(file, value, ';');
    cout << value << " ";
    getline(file, value, '\n');
    cout << value << "\n";

    //primo ciclo
    while (getline(file, intvalue)) {

        getline(file, intvalue, ';');
        JobTime.push_back(intvalue);
        getline(file, intvalue, ';');
        MachineId.push_back(intvalue);
        getline(file, intvalue, '\n');
        ProcTime.push_back(intvalue);
        //getline(file, intvalue, '\n');
    }

    for (i = 0; i <= ProcTime.size(); i++)
        cout << JobTime[i] << " " << MachineId[i] << " " << ProcTime[i] <<endl;

    cin >> intvalue;

    return 0;
}

The csv file is :

#Jobs;30
#Machines;2
#Resources;4

JobId;MachineId;PrTime
1;1;12
2;0;97
3;1;54
4;1;83
5;1;56
6;0;5
7;0;18
8;1;17
9;0;15
10;0;83

JobId;DueDate;RelDate;TardPenalty
1;575;4;1
2;563;70;2
3;483;1;8
4;519;68;1
5;540;64;10
6;546;126;8
7;550;2;6

Each table is separated by the others with one blank line. Can someone help me to read each table? Thanks a lot

5
  • Possible duplicate of How can I read and parse CSV files in C++? Commented Jan 20, 2016 at 15:27
  • @SimonKraemer posted a good answer. You didn't specify what issue you are having with the endline characters, but maybe this answer will help. Or at least get you going. Commented Jan 20, 2016 at 15:35
  • My issue is that when i have read the first table, my program continue to read the second table instead i want only read the first. Commented Jan 20, 2016 at 15:41
  • I would think that the link I shared would work then. You said each table is separated by a blank line, then if (entry == "") is true, then you could write it to your matrix and then maybe reset the stream? Commented Jan 20, 2016 at 15:47
  • 'entry' is a string? I cant adapt the code to my problem, it continue to read all table. Commented Jan 20, 2016 at 15:56

2 Answers 2

2

You can use the peek() function.
check for file.peek()!='\n'
The following code should work for you.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

using namespace std;

int i = 0, j = 0 , z=0;

int main()
{
    ifstream file("I_30_2_02_02_1.csv"); // declare file stream
    if(!file)
        return 0;
    string value;
    string intvalue;
    string check;
    int jobs;
    int machines;
    int resources;
    vector<string> JobTime;
    vector<string> MachineId;
    vector<string> ProcTime; //archiviato come JobId MachineId ProcTime

    //prime tre righe

    getline(file, value, ';'); // #jobs
    getline(file, intvalue, '\n');  
    jobs = stoi(intvalue);
    cout << "Jobs: " <<jobs << "\n";    

    getline(file, value, ';'); //#machines
    getline(file, intvalue, '\n');
    machines = stoi(intvalue);
    cout << "Machines: " << machines << "\n";

    getline(file, value, ';'); //#resources
    getline(file, intvalue, '\n');
    resources = stoi(intvalue);
    cout << "Resources: " << resources << "\n";

    //scritte inutili
    getline(file, value, ';');
    cout << value << " ";
    getline(file, value, ';');
    cout << value << " ";
    getline(file, value, '\n');
    cout << value << "\n";
    //primo ciclo
    while (file.peek()!='\n') 
    {

        getline(file, intvalue, ';');
        JobTime.push_back(intvalue);
        getline(file, intvalue, ';');
        MachineId.push_back(intvalue);
        getline(file, intvalue, '\n');
        ProcTime.push_back(intvalue);
        //getline(file, intvalue, '\n');
    }

    for (i = 0; i < ProcTime.size(); i++)
        cout << JobTime[i] << " " << MachineId[i] << " " << ProcTime[i] <<endl;

    cin >> intvalue;

return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Maybe try if (entry.empty()), or some condition like that. Also, I think that getline() returns the length of the line (0 being empty, so a blank line will be > 0). So it should be as simple as finding the size of the blank line.

while (getline(file, intvalue)) 
{
    if (intvalue > 0) 
    {
        getline(file, intvalue, ';');
        JobTime.push_back(intvalue);

        getline(file, intvalue, ';');
        MachineId.push_back(intvalue);

        getline(file, intvalue, '\n');
        ProcTime.push_back(intvalue);

    } else {
        break;
    }
}

Or something of the like. If intvalue > 0 doesn't work, then find what the size is of the empty line and use that as the condition.

EDIT: As an alternative, getline() can return a string as well. In my opinion, this has the benefit of being searchable. I wrote a quick example of this below.

size_t pos;
std::string str;
std::string token;
std::vector<std::string> line;

// get the entire line
while ( getline(file, str) )
{
    while ( (pos = str.find(';')) != std::string::npos)
    {
        // get content up to next semicolon     
        token = str.substr(0, pos);
        line.push_back(token);
        str.erase(0, pos + 1);
    }
    // get content to the end
    token = str.substr(0, pos);
    line.push_back(token);
}

The second while loop looks for each semicolon, pushes the content, and then erases it. After the while loop, the push_back() is for the rest of the line from the last semicolon to the end.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.