Разделение строки на основе нескольких разделителей строк в c ++ - PullRequest
0 голосов
/ 12 июня 2018

Я пишу свой код на C ++ 98, используя только стандартные библиотеки.Я пытаюсь написать некоторый код для разделения строки на несколько подстрок, каждая из которых ограничена строкой «ОК» или строкой «ОШИБКА».Каждая подстрока должна быть помещена в массив mysubstring.

Это код, который я написал для одного разделителя:

void split_string()
{
   for (unsigned short k=0;k<10;k++)
   {
      mysubstring[k]=""; //resetting all substrings
   }
   string separator = "OK";
   size_t pos = 0;
   unsigned short index=0;
   while ((pos = str_to_split.find(separator)) != std::string::npos) {
   mysubstring[index] = str_to_split.substr(0, pos);
   str_to_split.erase(0, pos + separator.length());
   index++;
}

Эта версия с одним разделителем работает нормально.Затем я попытался обновить до двух разделителей:

    void split_string()
    {
        for (unsigned short k=0;k<10;k++)
        {
            mysubstring[k]=""; //resetting all substrings
        }
        string okseparator = "OK";
        string koseparator = "ERROR";
        size_t  okpos = 0;
        size_t  kopos = 0;
        unsigned short index=0;
        while ((okpos = string_to_split.find(okseparator)) != std::string::npos)
       {
        while ((kopos = string_to_split.find(koseparator)) != std::string::npos)
          {
            if (okpos <= kopos)
            {
               mysubtring[index] = string_to_split.substr(0, okpos + okseparator.length());

               string_to_split.erase(0, okpos + okseparator.length());
               index++;
            }
            else
            {
                mysubstring[index] = string_to_split.substr(0, kopos + koseparator.length());
                string_to_split.erase(0, kopos + koseparator.length());
                index++;
            }
        }
    }

        while ((kopos = string_to_split.find(koseparator)) != std::string::npos)
        {
            mysubtring[index] = string_to_split.substr(0, kopos + koseparator.length());
            string_to_split.erase(0, kopos + koseparator.length());
            index++;
            }
}

Идея здесь заключается в том, что я остаюсь в первом цикле, пока не израсходуется все «ОК», затем он входит в последнее время, чтобы завершить все ».ОШИБКА "слева.Подстроки должны входить в массив mysubstring в том же порядке, в котором они находятся в исходной строке string_to_split.

К сожалению, я не могу заставить его работать, не могли бы вы помочь мне?

Пример для проверки ипроверить:

#include <iostream>
#include <string.h>

void split_string();

string str_to_split = "skdjfnsdjknfjk OK    fkjsnfjksdnfjnsdjkfn ERROR skjdfnjksdnf OK sjkdnfjksdnfjERROR jnfjnsdjfnsjdknfjkn       OK";

use namespace std;
int main()
{
  split_string();
  return 0;
}

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Разобрался:

    void split_string()
    {
        for (unsigned short k=0;k<10;k++)
        {
            mysubstring[k]=""; //resetting all substrings
        }

    string okseparator = "OK";
    string koseparator = "ERROR";
    size_t okpos = 0;
    size_t kopos = 0;
    unsigned short  index=0;

    while (1)
        {
        okpos = string_to_split.find(okseparator);
        kopos = string_to_split.find(koseparator);
        if (okpos < kopos)
        {
            mysubstring[index] = string_to_split.substr(0, okpos + okseparator.length());
            string_to_split.erase(0, okpos + okseparator.length());
            index++;
        }
        else if (okpos > kopos)
        {
            mysubstring[index] = string_to_split.substr(0, kopos);
            string_to_split.erase(0, kopos + koseparator.length());
            index++;
        }
        else
        {
            break;
        }
        }
}

Я получаю позицию для обоих разделителей, но я рассматриваю только самый близкий.Оператор while (1) завершается, когда оба разделителя имеют одинаковую позицию (string :: npos = max (size_t)).

0 голосов
/ 12 июня 2018

Проверьте этот первый анализатор конечного автомата

Действительно примитивный пример для вашего сценария:

#include <iostream>
#include <vector>
#include <string>
#include <cstring>


void print_tokens(const std::vector<std::string>& tokens)
{
    for(std::vector<std::string>::const_iterator it = tokens.cbegin(); it != tokens.cend(); ++it)
        std::cout << *it << ' ';
    std::cout << std::endl;
}

int main()
{
    //std::string to_split = "AAAOKBBEBEBERERRORCCCOK";
    std::string to_split = "skdjfnsdjknfjk OK    fkjsnfjksdnfjnsdjkfn ERROR skjdfnjksdnf OK sjkdnfjksdnfjERROR jnfjnsdjfnsjdknfjkn       OK";

    std::vector<std::string> ok_tokens;
    std::vector<std::string> error_tokens;

    const unsigned short OK_TOK = ('O' << 8) | 'K';
    const unsigned short ER_TOK = ('E' << 8) | 'R';

    std::string::iterator  s = to_split.begin();
    unsigned short lex = *s;
    std::string token;

    while(to_split.end() != s) {
        lex = lex << 8 | *s;
        switch(lex) {
        case OK_TOK:
            if(!token.empty()) {
                ok_tokens.push_back( std::string( token.begin(), token.end() - 1)  );
                token.clear();
            }
            ++s;
            continue;
        case ER_TOK:
            if( std::string(s-1, s+4) == "ERROR"  && !token.empty()) {
                error_tokens.push_back( std::string( token.begin(), token.end() - 1) );
                token.clear();
                s += 4;
            }
            continue;
        }
        token.push_back( *s );
        ++s;
    }
    std::cout << "OK tokens: \n \t";
    print_tokens(ok_tokens);
    std::cout << "ERROR tokens: \n \t";
    print_tokens(error_tokens);
    std::cout.flush();

    return 0;
}
...