具有多个分隔符的字符串标记符,包括没有Boost的分隔符

use*_*015 12 c++ string tokenize

我需要在C++中创建字符串解析器.我试过用

vector<string> Tokenize(const string& strInput, const string& strDelims)
{
 vector<string> vS;

 string strOne = strInput;
 string delimiters = strDelims;

 int startpos = 0;
 int pos = strOne.find_first_of(delimiters, startpos);

 while (string::npos != pos || string::npos != startpos)
 {
  if(strOne.substr(startpos, pos - startpos) != "")
   vS.push_back(strOne.substr(startpos, pos - startpos));

  // if delimiter is a new line (\n) then add new line
  if(strOne.substr(pos, 1) == "\n")
   vS.push_back("\\n");
  // else if the delimiter is not a space
  else if (strOne.substr(pos, 1) != " ")
   vS.push_back(strOne.substr(pos, 1));

  if( string::npos == strOne.find_first_not_of(delimiters, pos) )
   startpos = strOne.find_first_not_of(delimiters, pos);
  else
   startpos = pos + 1;

        pos = strOne.find_first_of(delimiters, startpos);

 }

 return vS;
}
Run Code Online (Sandbox Code Playgroud)

适用于2X + 7cos(3Y)

(tokenizer("2X+7cos(3Y)","+-/^() \t");)

但是给出了2X的运行时错误

我需要非Boost解决方案.

我尝试使用C++ String Toolkit(StrTk)Tokenizer

std::vector<std::string> results;
strtk::split(delimiter, source,
             strtk::range_to_type_back_inserter(results),
             strtk::tokenize_options::include_all_delimiters);

 return results; 
Run Code Online (Sandbox Code Playgroud)

但它不会将令牌作为单独的字符串.

例如:如果我将输入设为2X + 3Y

输出向量包含

2X +

3Y

use*_*301 1

循环退出条件被破坏:

while (string::npos != pos || string::npos != startpos)
Run Code Online (Sandbox Code Playgroud)

允许输入,例如 pos = npos 且 startpos = 1。

所以

strOne.substr(startpos, pos - startpos)
strOne.substr(1, npos - 1)
Run Code Online (Sandbox Code Playgroud)

end 不是 npos,所以 substr 没有停止在它应该停止的地方,然后轰隆隆!

如果 pos = npos 且 startpos = 0,

strOne.substr(startpos, pos - startpos)
Run Code Online (Sandbox Code Playgroud)

生活,但是

strOne.substr(pos, 1) == "\n"
strOne.substr(npos, 1) == "\n"
Run Code Online (Sandbox Code Playgroud)

死了。也是如此

strOne.substr(pos, 1) != " "
Run Code Online (Sandbox Code Playgroud)

遗憾的是我没时间,现在无法解决这个问题,但 QuestionC 的想法是正确的。更好的过滤。大致如下:

    if (string::npos != pos)
    {
        if (strOne.substr(pos, 1) == "\n") // can possibly simplify this with strOne[pos] == '\n'
            vS.push_back("\\n");
        // else if the delimiter is not a space
        else if (strOne[pos] != ' ')
            vS.push_back(strOne.substr(pos, 1));
    }
Run Code Online (Sandbox Code Playgroud)