2013-06-16 3 views
0

다음 코드를 사용하여 여러 개의 .dat 파일을 읽고 구문 분석했습니다. 이 코드는 3D 벡터를 사용하여 읽기 프로세스 후 데이터를 저장합니다. 그러나 각 단일 파일에 해당하는 데이터는 다른 파일과 독립적이어야합니다. 문제는 파일의 수는 다양하며 컴파일시에는 알 수 없다는 것입니다. 따라서 벡터의 수 역시 달라집니다. 나는 이것을위한 어떤 해결책이 있는지 알고 싶다.알 수없는 파일 수의 데이터 저장

vector<vector<vector<string>>> masterList; 

for (int i = 0; i < files.size(); ++i) { 
    cout << "file name: " << files[i] << endl; 

    fin.open(files[i].c_str()); 
    if (!fin.is_open()) { 
     // error occurs!! 
     // break or exit according to your needs 
     cout<<"error"<<endl; 
    } 

    std::vector<vector<string>> tokens; 

    int current_line = 0; 
    std::string line; 
    while (std::getline(fin, line)) 
    { 

     cout<<"line number: "<<current_line<<endl; 
     // Create an empty vector for this line 
     tokens.push_back(vector<string>()); 

     //copy line into is 
     std::istringstream is(line); 
     std::string token; 
     int n = 0; 

     //parsing 
     while (getline(is, token, DELIMITER)) 
     { 
      tokens[current_line].push_back(token); 
      cout<<"token["<<current_line<<"]["<<n<<"] = " << token <<endl; 

      n++; 
     } 
     cout<<"\n"; 
     current_line++; 
    } 
    fin.clear(); 
    fin.close(); 
    masterList.push_back(tokens); 
} 

그래서, 내가 직면하고있어 주요 문제는 : 내가 컴파일에 얼마나 많은 파일 모를 때, 각각의 단일 파일에 해당하는 데이터를 저장하는 2D 벡터의 변수 번호를 만드는 방법 시각.

+2

3D 벡터는 가변 개수의 2D 벡터를 보유합니다. 이미 3D 벡터가 있으므로 원하는 내용을 잘 모릅니다. – interjay

+0

오류, 완전히 잃어 버렸습니다. 게시 된 코드의 문제점은 무엇입니까? 그것은 당신이 요구하는대로 정확하게 행동하는 것 같습니다. –

+0

@interjay 문제는 각 파일을 별도의 벡터에 저장하는 것이므로 나중에이 벡터를 별도로 사용할 수 있습니다. – Hawk

답변

1

"마스터 데이터"의 크기에 맞춰 주 파일 목록을 수정하십시오. 파일 이름의 길이가 가변적이면 먼저 구문 분석 (또는 한 가지 방법 또는 다른 방법으로 먼저 가져 오기) 한 다음 dat 파일에 대한 구문 분석을 실행합니다. 파일 이름이 런타임에만 알려지고 비동기 적으로 알려지면 새 파일 이름을 얻을 때마다 목록에 새 요소를 추가하십시오 (예를 들어 이벤트를 사용할 수 있습니다, https://github.com/Sheljohn/siglot 참조).

목록 요소는 메모리에서 독립적이며 목록은 상수 시간에 삭제/삽입을 지원합니다. 이렇게하면 각 파일에 해당하는 데이터가 다른 파일과 독립적입니다. 파일에 대한 특정 데이터를 검색하려면 목록에서 반복하여 해당 파일 (선형 시간)을 찾거나 unordered_map (상각 된 일정 시간) 목록을 교환하십시오.

#include <string> 
#include <list> 
#include <vector> 
#include <iostream> 
#include <sstream> 
#include <fstream> 
#include <iterator> 
#include <algorithm> 

using namespace std; 

#define AVG_LINES_PER_FILE 100 



/** 
* [tokenize_string Tokenize input string 'words' and put elements in vector 'tokens'.] 
* @param words [Space separated data-string.] 
* @param tokens [Vector of strings.] 
*/ 
void tokenize_string(string& words, vector<string>& tokens) 
{ 
    unsigned n = count(words.begin(), words.end(), ' '); 
    tokens.reserve(n); 

    istringstream iss(words); 
    copy( 
     istream_iterator<string>(iss), 
     istream_iterator<string>(), 
     back_inserter<vector<string> >(tokens) 
    ); 
} 



/** 
* Contains data parsed from a single .dat file 
*/ 
class DATFileData 
{ 
public: 

    typedef vector<string> line_type; 
    typedef vector<line_type> data_type; 

    DATFileData(const char* fname = nullptr) 
     { 
      m_fdata.reserve(AVG_LINES_PER_FILE); 
      m_fdata.clear(); 

      if (fname) parse_file(fname); 
     } 

    // Check if the object contains data 
    inline operator bool() const { return m_fdata.size(); } 

    // Parse file 
    bool parse_file(const char* fname) 
     { 
      string line; 
      m_fdata.clear(); 
      ifstream fin(fname); 

      if (fin.is_open()) 
      { 
       while (fin.good()) 
       { 
        getline(fin,line); 
        m_fdata.push_back(line_type()); 
        tokenize_string(line, m_fdata.back()); 
       } 
       fin.close(); 

       m_fname = fname; 
       cout << "Parsed " << m_fdata.size() << " lines in file '" << fname << "'." << endl; 
       return true; 

      } 
      else 
      { 
       cerr << "Could not parse file '" << fname << "'!" << endl; 
       return false; 
      } 
     } 

    // Get data 
    inline unsigned size() const { return m_fdata.size(); } 
    inline const char* filename() const { return m_fname.empty() ? nullptr : m_fname.c_str(); } 
    inline const data_type& data() const { return m_fdata; } 
    inline const line_type& line(const unsigned& i) const { return m_fdata.at(i); } 

private: 

    string m_fname; 
    data_type m_fdata; 
}; 



int main() 
{ 

    unsigned fcount = 0; 
    vector<string> files = {"some/file/path.dat","another/one.dat"}; 
    list<DATFileData> data(files.size()); 

    for (DATFileData& d: data) 
     d.parse_file(files[fcount++].c_str()); 

    cout << endl << files.size() << " files parsed successfully." << endl; 
} 
관련 문제