在c ++中基于多个字符串分隔符拆分字符串

时间:2018-06-12 18:38:42

标签: c++ string c++98

我只使用标准库在C ++ 98中编写代码。 我正在尝试编写一些代码来分割多个子字符串中的字符串,每个子字符串由字符串“OK”或字符串“ERROR”分隔。 每个子字符串都应该放在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++;
            }
}

这里的想法是我留在第一个while循环中,直到所有“OK”被消耗,然后它进入最后一个完成所有“ERROR”左边。 子串应该按照它们在string_to_split原始字符串中的顺序进入mysubstring数组。

可悲的是,我无法让它发挥作用,你能帮助我吗?

测试和验证的示例:

#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 :(得分:0)

首先检查finite state machine parser

您的方案的一个非常原始的示例:

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

答案 1 :(得分:0)

想出来:

sw $ra, 64($sp)

我得到两个分隔符的位置,但我认为只有最接近的分隔符。 当两个分隔符具有相同的位置时,while(1)终止(string :: npos = max(size_t))。