Фильтрация данных CSV с помощью c++

извините за вопрос, который многие могут подумать, что уже был задан.

у меня очень длинный файл данных CSV (dat.csv) с 5 столбцами. У меня есть еще один короткий CSV (фильтр.csv) файл с 1 столбцом.

Теперь мне нужно только извлечь столбцы из dat.csv, где столбец-1 соответствует столбцу-1 фильтра.csv.

Я обычно делаю это в BASH, используя sed/awk. Однако по некоторым другим причинам мне нужно сделать это в файле C++. Можете ли вы предложить эффективный способ сделать это?

Пример Данных:

данные.csv

ID,Name,CountryCode,District,Population

3793,NewYork,USA,NewYork,8008278
3794,LosAngeles,USA,California,3694820
3795,Chicago,USA,Illinois,2896016
3796,Houston,USA,Texas,1953631
3797,Philadelphia,USA,Pennsylvania,1517550
3798,Phoenix,USA ,Arizona,1321045
3799,SanDiego,USA,California,1223400
3800,Dallas,USA,Texas,1188580
3801,SanAntonio,USA,Texas,1144646
.csv
3793
3797
3798

2 ответов


вот несколько советов:

  1. поток, из которого Вы читаете данные, должен игнорировать запятые, поэтому он должен установить запятые в пробелы с помощью std::ctype<char> фасет проникнут в его локали. Вот пример изменения классификационной таблицы:

    struct ctype : std::ctype<char>
    {
    private:
        static mask* get_table()
        {
            static std::vector<mask> v(classic_table(),
                                       classic_table() + table_size);
    
            v[','] &= ~space;
            return &v[0];
        }
    public:
        ctype() : std::ctype<char>(get_table()) { }
    };
    
  2. прочитайте первый csv. файл строки-мудрые (что означает std::getline()). Извлеките первое слово и сравните его с извлечением из второго .CSV-файл. Продолжать это пока вы не дойдете до конца первого файла:

    int main()
    {
        std::ifstream in1("test1.csv");
        std::ifstream in2("test2.csv");
    
        typedef std::istream_iterator<std::string> It;
    
        in1 >> comma_whitespace;
        in2 >> comma_whitespace;
    
        std::vector<std::string> in2_content(It(in2), It());
        std::vector<std::string> matches;
    
        while (std::getline(in1, line))
        {
            std::istringstream iss(line);
            It beg(iss);
    
            if (std::find(in2_content.begin(),
                          in2_content.end(), *beg) != in2_content.end())
            {
                matches.push_back(line);
            }
        }
    }
    
    // After the above, the vector matches should hold all the rows that
    // have the same ID number as in the second csv file
    

    comma_whitespace - это манипулятор, который меняет локаль на заказ ctype определено выше.

    отказ от ответственности: я не проверял этот код.


этого .библиотека сортировки csv может помочь:

http://www.partow.net/programming/dsvfilter/index.html

вы можете объединить столбцы обеих таблиц в одну большую таблицу, а затем запросить совпадения в новой таблице (где столбец 1 таблицы A и столбец 1 таблицы B). Или, может быть, эта библиотека имеет функции для сравнения таблиц.