4

次のような大きな CSV ファイルがあります。

23456、The End is Near、意味のないばかげた説明、http: //www.example.com、45332、1998 年 7 月 5 日、日曜日、45.332

これは、CSV ファイルの 1 行にすぎません。これらの約500kがあります。

C++ を使用してこのファイルを解析したいと考えています。私が始めたコードは次のとおりです。

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

using namespace std;

int main()
{
    // open the input csv file containing training data
    ifstream inputFile("my.csv");

    string line;

    while (getline(inputFile, line, ','))
    {
        istringstream ss(line);

        // declaring appropriate variables present in csv file
        long unsigned id;
        string url, title, description, datetaken;
        float val1, val2;

        ss >> id >> url >> title >> datetaken >> description >> val1 >> val2;

        cout << url << endl;
    }
    inputFile.close();
}

問題は、正しい値が出力されないことです。

フィールド内の空白を処理できないと思われます。それで、あなたは私が何をすべきだと提案しますか?

ありがとう

4

5 に答える 5

4

この例では、 two を使用して文字列を解析する必要がありますgetlinegetline(cin, line)1 つ目は、デフォルトの改行区切り文字を使用して cvs テキストの行を取得します。2 番目のgetline(ss, line, ',')区切りは、コンマを使用して文字列を区切ります。

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

float get_float(const std::string& s) { 
    std::stringstream ss(s);
    float ret;
    ss >> ret;
    return ret;
}


int get_int(const std::string& s) { 
    std::stringstream ss(s);
    int ret;
    ss >> ret;
    return ret;
}

int main() {
    std::string line;
    while (getline(cin, line)) {
        std::stringstream ss(line);
        std::vector<std::string> v;
        std::string field;
        while(getline(ss, field, ',')) {
            std::cout << " " << field;
            v.push_back(field);
        }
        int id = get_int(v[0]);
        float f = get_float(v[6]);
        std::cout << v[3] << std::endl;
    }
}

于 2013-08-16T13:50:29.340 に答える
0

フィールド値内の空白が原因で、コードが意図したとおりに動作していないと考えるのは正しいことです。

フィールド値内にコンマを含むフィールドがない「単純な」CSV がある場合は、ストリーム演算子とおそらく C++ をすべて一緒に使用しないでください。問題のサンプル プログラムは、フィールドを並べ替えるだけです。値を実際に解釈したり、適切な型に変換したりする必要はありません (検証も目的である場合を除きます)。awk を使用すると、単独で並べ替えを行うのは非常に簡単です。たとえば、次のコマンドは、単純な CSV ファイルにある 3 つのフィールドを逆にします。

cat infile | awk -F, '{ print $3","$2","$1 }' > outfile

このコード スニペットを、より大きくより良いアイデアの出発点として使用することが本当に目的である場合は、コンマを検索して行をトークン化します。std::string クラスには、オフセット固有の文字を見つけるための組み込みメソッドがあります。このアプローチは、必要に応じてエレガントまたは非エレガントにすることができます。最も洗練されたアプローチは、ブースト トークン化コードのようなものになります。

手っ取り早い方法は、プログラムに N 個のフィールドがあることを知り、対応する N-1 個のコンマの位置を探すことです。これらの位置を取得したら、 std::string::substr を呼び出して対象のフィールドを抽出するのは非常に簡単です。

于 2017-01-06T02:47:10.607 に答える