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 ベクトルを作成して、各ファイルに対応するデータを格納する方法です。

4

1 に答える 1

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;
}
于 2013-06-16T14:12:49.243 に答える