478 Stimmen

Wie kann ich eine Zeichenkette in C++ tokenisieren?

Java verfügt über eine praktische Split-Methode:

String str = "The quick brown fox";
String[] results = str.split(" ");

Gibt es eine einfache Möglichkeit, dies in C++ zu tun?

234 Stimmen

Ich kann nicht glauben, dass diese Routineaufgabe in C++ so viel Kopfzerbrechen macht

6 Stimmen

Seine nicht Kopfschmerzen in C + + - es gibt verschiedene Möglichkeiten, um es zu erreichen. Programmierer sind weniger bewusst, C + + als c # - seine über Marketing und Investitionen ... siehe dies für verschiedene C + + Optionen, um das gleiche zu erreichen: cplusplus.com/faq/sequenzen/strings/split

11 Stimmen

@hB0 gehen durch viele Fragen Antworten und immer noch nicht entscheiden, bedeutet, ist ein Kopfschmerz. die eine braucht, dass die Bibliothek, die andere ist nur für Leerzeichen, die andere nicht behandeln Leerzeichen.

28voto

sivabudh Punkte 30515

Ich weiß, dass Sie nach einer C++-Lösung gefragt haben, aber vielleicht hilft Ihnen das hier weiter:

Qt

#include <QString>

...

QString str = "The quick brown fox"; 
QStringList results = str.split(" "); 

Der Vorteil gegenüber Boost ist in diesem Beispiel, dass es sich um eine direkte Eins-zu-eins-Zuordnung zum Code Ihres Beitrags handelt.

Siehe mehr unter Qt-Dokumentation

23voto

vzczc Punkte 8712

Hier ist ein Beispiel für eine Tokenizer-Klasse, die das tun könnte, was Sie wollen

//Header file
class Tokenizer 
{
    public:
        static const std::string DELIMITERS;
        Tokenizer(const std::string& str);
        Tokenizer(const std::string& str, const std::string& delimiters);
        bool NextToken();
        bool NextToken(const std::string& delimiters);
        const std::string GetToken() const;
        void Reset();
    protected:
        size_t m_offset;
        const std::string m_string;
        std::string m_token;
        std::string m_delimiters;
};

//CPP file
const std::string Tokenizer::DELIMITERS(" \t\n\r");

Tokenizer::Tokenizer(const std::string& s) :
    m_string(s), 
    m_offset(0), 
    m_delimiters(DELIMITERS) {}

Tokenizer::Tokenizer(const std::string& s, const std::string& delimiters) :
    m_string(s), 
    m_offset(0), 
    m_delimiters(delimiters) {}

bool Tokenizer::NextToken() 
{
    return NextToken(m_delimiters);
}

bool Tokenizer::NextToken(const std::string& delimiters) 
{
    size_t i = m_string.find_first_not_of(delimiters, m_offset);
    if (std::string::npos == i) 
    {
        m_offset = m_string.length();
        return false;
    }

    size_t j = m_string.find_first_of(delimiters, i);
    if (std::string::npos == j) 
    {
        m_token = m_string.substr(i);
        m_offset = m_string.length();
        return true;
    }

    m_token = m_string.substr(i, j - i);
    m_offset = j;
    return true;
}

Beispiel:

std::vector <std::string> v;
Tokenizer s("split this string", " ");
while (s.NextToken())
{
    v.push_back(s.GetToken());
}

16voto

dbr Punkte 158949

pystring ist eine kleine Bibliothek, die eine Reihe von Python-String-Funktionen implementiert, darunter auch die Split-Methode:

#include <string>
#include <vector>
#include "pystring.h"

std::vector<std::string> chunks;
pystring::split("this string", chunks);

// also can specify a separator
pystring::split("this-string", chunks, "-");

12voto

einpoklum Punkte 100527

Wenn Sie C++-Bereiche verwenden - die vollständige Bereiche-v3 Bibliothek, nicht die eingeschränkte Funktionalität, die in C++20 akzeptiert wird - Sie könnten es so machen:

auto results = str | ranges::views::tokenize(" ",1);

... und dies wird faul ausgewertet. Sie können alternativ einen Vektor auf diesen Bereich setzen:

auto results = str | ranges::views::tokenize(" ",1) | ranges::to<std::vector>();

dies benötigt O(m) Platz und O(n) Zeit, wenn str hat n Zeichen, die m Wörter bilden.

Siehe auch das bibliothekseigene Tokenisierungsbeispiel, aquí .

11voto

DannyK Punkte 1334

Ich habe diese Antwort auf eine ähnliche Frage gepostet.
Erfinden Sie das Rad nicht neu. Ich habe eine Reihe von Bibliotheken verwendet und die schnellste und flexibelste, die ich gefunden habe, ist: C++ String Toolkit Bibliothek .

Hier ist ein Beispiel, wie man es verwendet, das ich an anderer Stelle im Stackoverflow gepostet habe.

#include <iostream>
#include <vector>
#include <string>
#include <strtk.hpp>

const char *whitespace  = " \t\r\n\f";
const char *whitespace_and_punctuation  = " \t\r\n\f;,=";

int main()
{
    {   // normal parsing of a string into a vector of strings
       std::string s("Somewhere down the road");
       std::vector<std::string> result;
       if( strtk::parse( s, whitespace, result ) )
       {
           for(size_t i = 0; i < result.size(); ++i )
            std::cout << result[i] << std::endl;
       }
    }

    {  // parsing a string into a vector of floats with other separators
       // besides spaces

       std::string s("3.0, 3.14; 4.0");
       std::vector<float> values;
       if( strtk::parse( s, whitespace_and_punctuation, values ) )
       {
           for(size_t i = 0; i < values.size(); ++i )
            std::cout << values[i] << std::endl;
       }
    }

    {  // parsing a string into specific variables

       std::string s("angle = 45; radius = 9.9");
       std::string w1, w2;
       float v1, v2;
       if( strtk::parse( s, whitespace_and_punctuation, w1, v1, w2, v2) )
       {
           std::cout << "word " << w1 << ", value " << v1 << std::endl;
           std::cout << "word " << w2 << ", value " << v2 << std::endl;
       }
    }

    return 0;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X