2016-01-20 5 views
1

Мне нужно проанализировать несколько файлов csv с одной и той же базовой структурой, и мне нужно сохранить значения в разных матрицах. Я хотел бы сохранить каждую таблицу в одной матрице, но проблема в том, что у меня есть некоторые проблемы с символом конца строки. Я попытался использовать функцию getline, но я не могу завершить цикл while, когда таблица анализируется.Parse csv file C++

Я использую этот код:

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

Каждая таблица отделяется от других с одной пустой строкой. Может кто-нибудь помочь мне прочитать каждый стол? Большое спасибо

+0

Возможный дубликат [Как я могу читать и анализировать CSV-файлы в C++?] (Http://stackoverflow.com/questions/1120140/how-can-i-read-and-parse-csv-files -in-c) –

+0

@SimonKraemer опубликовал хороший ответ. Вы не указали, какая у вас проблема с символами конечной линии, но, возможно, [этот ответ] (http://stackoverflow.com/a/15328493/2744444) поможет. Или, по крайней мере, ты пойдешь. – bratak

+0

Моя проблема в том, что когда я прочитал первую таблицу, моя программа продолжает читать вторую таблицу, вместо этого хочу только прочитать первый. – user3836982

ответ

1

Возможно, попробуйте 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 не работает, то найдите размер пустой строки и используйте это как условие.

EDIT: В качестве альтернативы 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() для остальной части строки от последней точки с запятой до конца.

2

Вы можете использовать функцию peek().
check for file.peek()! = '\ N'
Следующий код должен работать на вас.

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

Спасибо большое! он работает для моей проблемы! – user3836982