6

これが尋ねられた場合は申し訳ありませんが、私に役立つ解決策が見つからないようです。テキスト ファイルからデータを読み込んで、最終的にオブジェクトに格納しようとしています。

テキスト ファイルには、カンマで区切られた 4 つの変数が含まれています。

私は次のようにこれをやろうとしました:

string v1, v2, v3, v4;
ifstream afile;
afile.open("thefile.txt");
afile >> v1 >> v2 >> v3 >> v4;
afile.close();
cout << v1 << endl;
cout << v2 << endl;
cout << v3 << endl;
cout << v4 << endl;

ファイルには複数のレコードがあります。今のところ、動作することを確認するために 1 だけを実行しようとしましたが、データを読み込むときにコンマで区切られません。

そこから、データをオブジェクトに保存したいと思います。次のように動作しますか: Thing* thing1 = new Thing(v1, v2, v3, v4);

ただし、たとえば 5 つのレコードを読み込む場合、上記のコード行を構成する最良の方法は何でしょうか? 各オブジェクトには一意の名前が必要なので、おそらく for ループとベクトルを使用して反復できる方法はありますか? ie for (int i = 0; i < 5; i++) { // データを読み込み // ベクトルに格納 }

どんなヒントでも大歓迎です

4

3 に答える 3

8

CSV 形式は、単なるコンマ区切りよりも複雑です。エスケープし、それに応じて解釈する必要がある引用符を含めることができ、さまざまな区切り文字が許可される場合があります。入力ファイルが厳密にフォーマットされていない場合は、専用の CSV インポート/エクスポート ライブラリを使用する必要があります。

トークナイザー クラスがあなたの質問に答えるかもしれません ( boostからのものや、より単純なものが利用可能です)。

この件に関する他の 質問を確認する必要があります。

于 2012-09-02T05:50:55.120 に答える
6

@Soravuxの回答に注意し、可能であれば専用のライブラリを使用してください。特に、彼が提案する strtk ツールキットは興味深いようで、1 つのヘッダーにすぎません。Boost は、少なくとも 5 つの異なる方法でそれを行うこともできます。C++ をしばらく使用する場合は、学習する価値のあるライブラリです。とは言っても、これらのソリューションはすべてプログラムに複雑さを追加するものであり、特に必要なものが非常に単純な数値リーダーだけである場合は、その労力を別の場所に費やす可能性があります。以下は、標準 C++ (ベクトルやストリームなどの STL を使用) で実行する方法です。

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

    using namespace std;

    vector<double> &split(const string &s, 
        char delim, vector<double> &elems) 
    {
        stringstream ss(s);
        string item;
        while (std::getline(ss, item, delim)) {
            stringstream conv( item );
            double number;
            conv >> number;
            elems.push_back(number);
        }
        return elems;
    }

    struct my_record_t{
        double f1, f2, f3, f4;
    };

    typedef vector<my_record_t> my_record_vector_t;

    int main( int argc, char* argv[])
    {
        stringstream  in("10,20,2.0,5\n"
                          "4.,5.,6.,80\n"
                          "4.,2.,6.,70\n"
                          "4.,5.,6.,86\n"
                          "2.,5.,9.,80\n");
        // Or alternatively, :
        //    ifstream in("myfile.csv");

        // Here you store your records
        my_record_vector_t mrv;

        string line;
        vector< double > numbers; 
        while( std::getline( in, line, '\n' ) )
        {
            numbers.clear();
            split( line, ',', numbers);
            my_record_t r;
            r.f1 = numbers[0];
            r.f2 = numbers[1];
            r.f3 = numbers[2];
            r.f4 = numbers[3];
            mrv.push_back( r );
        }

        cout << mrv.size() << " records read" << endl;


        return 0;
    }

少し長すぎるかもしれませんが、1 日を節約できます。

于 2012-09-02T06:08:56.107 に答える
4

Using ifstream to read floats を見て、カンマの解析から始めます。CSV 形式はより複雑ですが、この例から始めることができます。この例では、テキストの解析と必要な構造要素への変換に非常に優れたString Toolkitを使用しています。

于 2015-07-27T15:14:12.730 に答える