解析&按行排序csv文件

时间:2012-04-30 11:42:23

标签: c++ file parsing

获得我的跳跃日志的这个csv文件,并希望在每个块(跳转记录)中排序,以便首先列出入门者,最后列出学生第二和可选摄像师。 目前他们是按各种顺序写的。

正在考虑读取并将块的每一行分配到变量中,然后使用空行作为循环控制器进行打印。我是在正确的轨道上吗? 更喜欢C ++中的解决方案帮助(一点点exp和编译器设置),但是我很灵活,并且希望今年夏天能够深入探讨任何推荐语言的细节。可能的Python或任何一本有CompSci的好书介绍。

任何建议&非常感谢!

第一个角色是角色:1,2,3。

角色(1,2,3),日期(yyymmdd),飞机起重机,名称 角色1是串联教练, 角色2是学生, 角色3自由落体相机(可选)

1,20100124,C206WR-L1,MAC PETE

2,20100124,C206WR-L1,HOWARD STEPH

3,20100124,C206WR-L1,JONES DAVE

,,,

2,20100124,C206WR-L3,ALLSOP BEX

1,20100124,C206WR-L3,MAC PETE

3,20100124,C206WR-L3,JONES DAVE

,,,

1,20100124,C206WR-L2,MAC PETE

3,20100124,C206WR-L2,LAUER FINCH

2,20100124,C206WR-L2,JONES DAVE

,,,

1,20100124,C206WR-L4,MAC PETE

3,20100124,C206WR-L4,LAUER FINCH

2,20100124,C206WR-L4,JONES DAVE

,,,

2,20100124,C206WR-L4,SMITH JOHN

1,20100124,C206WR-L4,MAC PETE

,,,

2,20100124,C206WR-L5,BROWN CLAIRE

3,20100124,C206WR-L5,JONES DAVE

1,20100124,C206WR-L5,MAC PETE

3 个答案:

答案 0 :(得分:0)

尝试使用std :: multimap在插入时对它们进行排序,也不要丢失任何数据,因为multimap可以有多个相同的键值。 (在这种情况下,键值将是角色编号。)因此,数据将按您的需要进行排序。

答案 1 :(得分:0)

您可以使用拆分功能将每个CSV行分解为vector<string>个变量。这是一个示例split函数,可以使用std :: string和char delimeter(在您的情况下为“,”)调用:

template<typename T>
static inline std::vector<std::basic_string<T>> split(const std::basic_string<T>& s, T c)
{
    std::vector<std::basic_string<T>> v;

    if (!s.length())
        return v;

    std::basic_string<T>::size_type i = 0, j = s.find(c);

    while (j != std::basic_string<T>::npos)
    {
        v.push_back(s.substr(i, j - i));
        i = ++j;
        j = s.find(c, j);
    }

    v.push_back(s.substr(i, s.length()));

    return v;
}

然后您可以按照您选择的顺序打印变量。

答案 2 :(得分:0)

有很多方法可以为这只猫提供皮肤,我会展示一种更接近我的方法:使用解析器生成器(例如AX,Spirit)。由于我非常熟悉AX,所以这里是数据结构的C ++语法:

using axe::shortcuts;

// for role you can use a digit, you can additionally contrain it
auto role_rule = _d;
// or you can use char literals instead
// auto role_rule = axe::r_any("123");

// for date you can use digits or axe::r_decimal, depending on what you want to do with it
auto year_rule = axe::r_many(_d, 4);
auto month_rule = _d & _d;
auto date_rule = _d & _d;

// aircraft-liftnumber: as far as I understand it's alpha-numeric
auto aircraft_rule = +_w & '-' & +_w;

// name is two alpha strings separated by spaces
auto first_name_rule = axe::r_alphastr();
auto last_name_rule = axe::r_alphastr();
auto name_rule = last_name_rule & +_ws & first_name_rule;

// a rule to extract all information from the line
std::string line; // read line from file
struct record {
unsigned role, year, month, day;
std::string aircraft, name;
};

record rec;

auto line_rule = role >> rec.role & ','
& year_rule >> rec.year & ','
& month_rule >> rec.month & ','
& day_rule >> rec.day & ','
& aircraft_rule >> rec.aircraft & ','
& name_rule >> rec.name & *_n;

std::vector<record> file_records;

auto file_rule = *(line_rule >> axe::e_ref([&](...)
{
   file_records.push_back(rec);
})) & _z;

// read your file to a vector without filtering
std::ifstream csv_file("filename", std::ios::binary);
std::vector<char> cvs_content(
   std::istreambuf_iterator<char>(cvs_file), 
   std::istreambuf_iterator<char>());

if(!file_rule(cvs_content.begin(), cvs_content.end()).matched())
   throw "file corrupt";
相关问题