как получить компоненты и найти CSV-файл - PullRequest
0 голосов
/ 27 мая 2020

int main () {

struct tokens : std::ctype<char>
{
    tokens() : std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        typedef std::ctype<char> cctype;
        static const cctype::mask *const_rc = cctype::classic_table();

        static cctype::mask rc[cctype::table_size];
        std::memcpy(rc, const_rc, cctype::table_size * sizeof(cctype::mask));

        rc['/'] = std::ctype_base::space;
        rc['$'] = std::ctype_base::space;
        return &rc[0];
    }
};

std::string FormatMsg = "AB/LK$VD$SA$PO";
cin >> FormatMsg;
std::stringstream ss(FormatMsg);
ss.imbue(std::locale(std::locale(), new tokens()));
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> vstrings(begin, end);
std::copy(vstrings.begin(), vstrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));


system("Pause");

}

Из этого кода я хочу получить AB, LK и SA и искать похожие компоненты из отдельных файлов CSV. Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 28 мая 2020

Этот вопрос требует std::regex.

Вы можете искать шаблоны, сопоставлять шаблоны или перебирать шаблоны.

И это можно использовать для разделения строки.

C ++ уже давно имеет встроенную и специальную функцию, специально разработанную для этой цели, для токенизации строк (разделения строк на токены). И поскольку такая простая специализированная функция, разработанная для этой цели, доступна, ее просто необходимо использовать. Нет необходимости во внешних библиотеках или сложных конструкциях. Просто используйте std::sregex_token_iterator.

Это итератор (как и многие другие итераторы), который перебирает токены (подстроки) строки. Итак, что мы хотим.

Затем мы можем использовать конструктор диапазона std::vector s, чтобы написать что-то простое вроде этого:

std::vector tokens(std::sregex_token_iterator(msg.begin(), msg.end(), delimiter, -1), {}));

Итак, мы определяем переменную с именем «tokens» "типа std::vector (с CTAD автоматически выводится тип вектора). Мы используем его конструктор диапазона и предоставляем итераторы начала и конца. Начальный итератор - это std::sregex_token_iterator, а конечный итератор - его инициализированный по умолчанию аналог. Просто {}.

Чтобы поместить такой вектор в 2D-вектор, мы используем функцию внешних векторов emplace_back и делаем внутреннее построение для внутреннего вектора.

Итак, вы читаете весь CSV-файл с 2 операторами

  • простой для l oop
  • простой возврат с помощью std::sregex_token_iterator
        // We will read all lines of the source file with a simple for loop and std::getline
        for (std::string msg{}; std::getline(csvFile, msg); ) {

            // We will split the one big string into tokens (sub-strings) and add it to our 2D array
            csvData.emplace_back(std::vector<std::string>(std::sregex_token_iterator(msg.begin(), msg.end(), delimiter, -1), {}));
        }

Это была теория. Практически это означает, что для вашего случая вам нужно только определить токены переменной и использовать ее конструктор. Никаких дополнительных заявлений не требуется. У нас обычно один лайнер.

Ваш код будет выглядеть так:

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <iterator>
#include <algorithm>

// Slash and $ are the delimiters
std::regex delimiter{ R"(\/|\$)" };

int main() {

    // The test data
    std::string msg = "AB/LK$VD$SA$PO";

    // Defining the variable token and initialize it using its range constructor
    std::vector tokens(std::sregex_token_iterator(msg.begin(), msg.end(), delimiter, -1), {});

    // Show result on the screen
    std::copy(tokens.begin(), tokens.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

    return 0;
}

Описание исходного файла не очень подробное. Я не знаю структуру ваших данных CSV.

Если есть другие строки в другом формате, вы можете добавить функцию std::regex_match с std::regex, например: ^[A-Z]{2}\/[A-Z]{2}((\$[A-Z]{2})+)$. Но все зависит от формата ваших строк.

Конечно, вы можете адаптировать свои регулярные выражения, и они вернут вам все, что вы хотите.

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