解析 csv 文件 c++

Parse csv file c++

本文关键字:c++ 文件 csv 解析      更新时间:2023-10-16

我必须解析几个具有相同基本结构的csv文件,并且必须将值保存在不同的矩阵中。我想将每个表保存在一个矩阵中,但问题是我对端行字符有一些问题。我尝试使用 getline 函数,但在解析表时无法终止 while 循环。

我使用此代码:

// 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;
}

csv 文件是 :

#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

每个表由其他表用一个空行分隔。有人可以帮我阅读每个表格吗?多谢

您可以使用 peek() 函数。
检查 file.peek()!=''
以下代码应该适合您。

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

也许尝试if (entry.empty()),或类似的条件。另外,我认为 getline() 返回行的长度(0 为空,因此空行将> 0)。所以它应该像找到空白行的大小一样简单。

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;
    }
}

或类似的东西。如果intvalue > 0不起作用,则找到空行的大小并将其用作条件。

编辑:作为替代方案,getline() 也可以返回一个字符串。在我看来,这具有可搜索性的好处。我在下面写了一个快速的例子。

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

第二个 while 循环查找每个分号,推送内容,然后擦除它。在 while 循环之后,push_back() 用于从最后一个分号到末尾的其余部分。