从文件中读取CSV数据

时间:2012-09-02 05:14:49

标签: c++

如果有人问过我很抱歉,但我似乎无法找到有助于我的解决方案。我正在尝试从文本文件中读取数据,并最终将其存储在对象中。

文本文件有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以确保它有效,但是当它读入数据时,它不会在逗号分隔。

从那里,我想将数据存储到一个对象中。以下工作如下:     事情* thing1 = new Thing(v1,v2,v3,v4);

虽然,当我读到5条记录时,构建上述代码行的最佳方法是什么?由于每个对象都需要一个唯一的名称,有没有办法可以使用for循环和向量进行迭代?即     for(int i = 0; i&lt; 5; i ++){         //读入数据         //存储在矢量中     }

非常感谢任何提示

3 个答案:

答案 0 :(得分:8)

CSV格式比逗号分隔符更复杂。它可以包含您应该转义的引号并相应地解释,并且可以允许不同的分隔符。如果您的输入文件没有严格格式化,那么您真的应该使用专用的CSV导入/导出库。

tokenizer类可以回答您的问题(例如来自boostsimpler ones的问题)。

您应该查看有关此主题的other questions

答案 1 :(得分:6)

如果可以,请注意@Soravux回答并使用专门的库。特别是,他建议的strtk工具包似乎很有趣,只是一个标题。 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;
    }

可能有点太长了,但它可以节省你的一天。

答案 2 :(得分:4)

我会看Using ifstream to read floats并开始解析逗号。 CSV格式更复杂,但示例应该让您入门。该示例使用String Toolkit,它非常擅长解析文本并转换为您需要的结构元素。