2015-06-12 3 views
5

ich eine Zeichenfolge zu spalten versuchen und es in einen Vektor setzenSplitting ein String aber halte leer Token C++

aber ich mag auch ein leeres Token halten, wenn es in Folge Trennzeichen:

Zum Beispiel :

string mystring = "::aa;;bb;cc;;c" 

Ich möchte diese Zeichenfolge auf Tokenize:; Trennzeichen aber dazwischen Trennzeichen wie :: und ;; Ich möchte meinen Vektor eine leere Zeichenfolge einschieben;

so my desired output for this string is: 

"" (empty) 
aa 
"" (empty) 
bb 
cc 
"" (empty) 
c 

Auch meine Anforderung ist nicht die Boost-Bibliothek zu verwenden.

falls mir eine Idee geben könnte.

dank

Code, der eine Zeichenfolge tokenize aber die leeren Token nicht

void Tokenize(const string& str,vector<string>& tokens, const string& delim) 
{ 
     // Skip delimiters at beginning. 
    string::size_type lastPos = str.find_first_not_of(delimiters, 0); 
    // Find first "non-delimiter". 
    string::size_type pos  = str.find_first_of(delimiters, lastPos); 

while (string::npos != pos || string::npos != lastPos) 
{ 
    // Found a token, add it to the vector. 
    tokens.push_back(str.substr(lastPos, pos - lastPos)); 
    // Skip delimiters. Note the "not_of" 
    lastPos = str.find_first_not_of(delimiters, pos); 
    // Find next "non-delimiter" 
    pos = str.find_first_of(delimiters, lastPos); 
    } 
} 
+1

Haben Sie versucht, irgendetwas? – Amit

+0

Ich habe versucht den Code oben, um meine Zeichenfolge zu symbolisieren, die funktioniert, aber nur sie ausschließen leere Token – XDProgrammer

+0

Warum fügen Sie nicht ein 'token.push_back (" "); direkt nach' tokens.push_back (strstr (lastPos, pos - lastPos)); '? – Bastien

Antwort

4

schließen Sie Ihren Algorithmus Arbeit mit einigen einfachen Änderungen vornehmen. Überspringe die Delimiter nicht zu Beginn, anstatt die Delimiter in der Mitte des Strings zu überspringen, erhöhe einfach die Position um eins. Auch Ihre npos Überprüfung sollte sicherstellen, dass beide Positionen sind nicht npos, so sollte es && anstelle von || sein.

void Tokenize(const string& str,vector<string>& tokens, const string& delimiters) 
{ 
    // Start at the beginning 
    string::size_type lastPos = 0; 
    // Find position of the first delimiter 
    string::size_type pos = str.find_first_of(delimiters, lastPos); 

    // While we still have string to read 
    while (string::npos != pos && string::npos != lastPos) 
    { 
     // Found a token, add it to the vector 
     tokens.push_back(str.substr(lastPos, pos - lastPos)); 
     // Look at the next token instead of skipping delimiters 
     lastPos = pos+1; 
     // Find the position of the next delimiter 
     pos = str.find_first_of(delimiters, lastPos); 
    } 

    // Push the last token 
    tokens.push_back(str.substr(lastPos, pos - lastPos)); 
} 
+0

* "// Find nächsten" non-delimiter "* beschreibt nicht, was' pos = str.find_first_of (delimiters, lastPos); 'tut, und Sie fügen das Token nicht nach dem letzten Delimiter (oder für ein' str 'ohne irgendein Begrenzer. Generieren Sie Annäherung ist Ton obwohl. –

+0

Should'nt Sie' tokens.push_back hinzufügen (strstr (lastPos, pos - lastPos)); 'am Ende, um die letzte Zeichenkette hinzuzufügen, wenn nicht leer? – Bastien

+0

Thanks , behoben .. – TartanLlama

2

Ich habe eine Version Iteratoren mit:

std::vector<std::string> split_from(const std::string& s 
    , const std::string& d, unsigned r = 20) 
{ 
    std::vector<std::string> v; 
    v.reserve(r); 

    auto pos = s.begin(); 
    auto end = pos; 

    while(end != s.end()) 
    { 
     end = std::find_first_of(pos, s.end(), d.begin(), d.end()); 
     v.emplace_back(pos, end); 
     pos = end + 1; 
    } 

    return v; 
} 

Mit Ihrer Schnittstelle:

void Tokenize(const std::string& s, std::vector<std::string>& tokens 
    , const std::string& delims) 
{ 
    auto pos = s.begin(); 
    auto end = pos; 

    while(end != s.end()) 
    { 
     end = std::find_first_of(pos, s.end(), delims.begin(), delims.end()); 
     tokens.emplace_back(pos, end); 
     pos = end + 1; 
    } 
} 
+0

sehr schön viel vereinfachter .. danke – XDProgrammer