C++ 按行分析和排序csv文件

C++ 按行分析和排序csv文件,c++,file,parsing,C++,File,Parsing,得到了我的跳转日志的csv文件,并希望在每个区块跳转记录中进行排序,以便首先列出指令员,其次是学生,最后是可选摄影师。 它们是按不同的顺序写的 认为读取并分配块的每一行为VARS,然后使用空白行作为循环控制项打印。我走对了吗? 希望C++中的解决方案帮助和一个编译器设置,但是AM Frasi,并希望真正进入今年夏天任何一个重新编译的语言的螺母和螺栓。可能是Python或任何一本介绍CompSci的好书 任何建议和参考非常感谢 第一列是角色:1,2,3 角色1,2,3,日期YYYYMMDD,航班号

得到了我的跳转日志的csv文件,并希望在每个区块跳转记录中进行排序,以便首先列出指令员,其次是学生,最后是可选摄影师。 它们是按不同的顺序写的

认为读取并分配块的每一行为VARS,然后使用空白行作为循环控制项打印。我走对了吗? 希望C++中的解决方案帮助和一个编译器设置,但是AM Frasi,并希望真正进入今年夏天任何一个重新编译的语言的螺母和螺栓。可能是Python或任何一本介绍CompSci的好书

任何建议和参考非常感谢

第一列是角色:1,2,3

角色1,2,3,日期YYYYMMDD,航班号,名称 角色1是串联讲师, 角色2是一名学生, 角色3自由落体照相机可选

120100124,C206WR-L1,MAC PETE

霍华德·斯蒂芬,C206WR-L1,220100124

琼斯·戴夫,C206WR-L1,320100124

,

220100124,C206WR-L3,ALLSOP BEX

120100124,C206WR-L3,MAC PETE

琼斯·戴夫,C206WR-L3,320100124

,

120100124,C206WR-L2,MAC PETE

320100124,C206WR-L2,劳尔雀

琼斯·戴夫,C206WR-L2,220100124

,

120100124,C206WR-L4,MAC PETE

320100124,C206WR-L4,劳尔雀

琼斯·戴夫,C206WR-L4,220100124

,

220100124,C206WR-L4,史密斯约翰

120100124,C206WR-L4,MAC PETE

,

220100124,C206WR-L5,布朗克莱尔

琼斯·戴夫,C206WR-L5,320100124


120100124、C206WR-L5、MAC PETE

尝试在插入时使用std::multimap对它们进行排序,同时不要丢失任何数据,因为multimap可以有多个相同的键值。键值将是本例中的角色编号。因此,数据将根据需要进行排序。

您可以使用拆分函数将每个CSV行分解为变量向量。下面是一个示例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;
}

然后你可以简单地按照你选择的顺序打印变量。

有很多方法可以剥这只猫的皮,我将展示一种更接近我的方法:使用解析器生成器,例如AXE、Spirit。因为我非常熟悉AXE,这里是一个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";

除非我误解了,OP希望对每一行进行排序,而不是将所有行排序到一个映射中。好的,那么对于每个数据块,他需要使用std::map,因为不会重复键值,并且每个块都被排序。