1

私のジャンプ日誌のこの csv ファイルを取得し、各ブロック (ジャンプ レコード) 内で並べ替えたいと考えています。これにより、インストラクターが最初に、生徒が 2 番目に、オプションのカメラマンが最後にリストされます。現在、それらはさまざまな順序で書かれています。

ブロックの各行を読み取って vars に割り当て、空白行をループ コントロールとして使用して印刷することを考えていました。私は正しい軌道に乗っていますか?C++ でのソリューション ヘルプ (少しの経験とコンパイラのセットアップ) を好むでしょうが、フレキシであり、この夏、推奨される言語の基本を実際に理解しようとしています。可能性のあるPythonまたはCompSciの入門書を備えた任意のもの。

アドバイスと参照は大歓迎です!

最初の列は役割です: 1,2,3.

role(1,2,3),date (yyymmdd),aircraft-liftnumber,name ロール 1 はタンデムインストラクター、ロール 2 は学生、ロール 3 フリーフォールカメラ (オプション)

1,20100124、C206WR-L1、マックピート

2,20100124、C206WR-L1、ハワード・ステフ

3,20100124、C206WR-L1、ジョーンズデイブ

、、、

2,20100124、C206WR-L3、ALLSOP BEX

1,20100124、C206WR-L3、マックピート

3,20100124、C206WR-L3、ジョーンズデイブ

、、、

1,20100124、C206WR-L2、マックピート

3,20100124,C206WR-L2,ラウアーフィンチ

2,20100124、C206WR-L2、ジョーンズデイブ

、、、

1,20100124、C206WR-L4、マックピート

3,20100124,C206WR-L4,ラウアーフィンチ

2,20100124、C206WR-L4、ジョーンズデイブ

、、、

2,20100124、C206WR-L4、スミスジョン

1,20100124、C206WR-L4、マックピート

、、、

2,20100124、C206WR-L5、ブラウンクレア

3,20100124、C206WR-L5、ジョーンズデイブ

1,20100124、C206WR-L5、マックピート

4

3 に答える 3

0

この猫の皮を剥ぐ方法はたくさんありますが、私に近いものを紹介します: パーサー ジェネレーター (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";
于 2012-05-01T19:52:03.187 に答える
0

分割関数を使用して、各 CSV 行をvector<string>変数に分割できます。std::string と char 区切り文字 (この場合は ",") で呼び出すことができる分割関数の例を次に示します。

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;
}

次に、選択した順序で変数を単純に出力できます。

于 2012-04-30T12:55:41.853 に答える
0

multimap は複数の同じキー値を持つ可能性があるため、std::multimap を使用して挿入中に並べ替え、データを失わないようにしてください。(この場合、キー値はロール番号になります。) したがって、データは思いどおりに並べ替えられます。

于 2012-04-30T12:04:16.763 に答える