String-Tokenizer mit mehreren Trennzeichen, einschließlich Trennzeichen ohne Boost

String-Tokenizer mit mehreren Trennzeichen, einschließlich Trennzeichen ohne Boost


Ich muss einen String-Parser in C++ erstellen. Ich habe es mit

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

Dies funktioniert für 2X+7cos(3Y)


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


Gibt aber einen Laufzeitfehler für 2X


Ich brauche eine Nicht-Boost-Lösung.


Ich habe versucht, C++ String Toolkit (StrTk) Tokenizer

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

aber es gibt Token nicht als separaten String aus.


zB:wenn ich die Eingabe als 2X+3Y gebe


Ausgabevektor enthält


2X+


3 Jahre


Antworten:


Schleifenausgangsbedingung ist gebrochen:


while (string::npos != pos || string::npos != startpos)

Erlaubt den Eintrag mit, sagen wir pos =npos und startpos =1.


Also


strOne.substr(startpos, pos - startpos)
strOne.substr(1, npos - 1)

end ist nicht npos, also endet substr nicht dort, wo es sollte, und BOOM!


Wenn pos =npos und startpos =0,


strOne.substr(startpos, pos - startpos)

lebt, aber


strOne.substr(pos, 1) == "\n"
strOne.substr(npos, 1) == "\n"

stirbt. So auch


strOne.substr(pos, 1) != " "

Leider habe ich keine Zeit mehr und kann das jetzt nicht lösen, aber QuestionC hat die richtige Idee. Besser filtern. Etwas in der Art von:


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