Wie tokenisiere ich einen String in C++?

Lesezeit: 7 Minuten

Wie tokenisiere ich einen String in C
Bill die Eidechse

Java hat eine bequeme Split-Methode:

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

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

  • Ich kann nicht glauben, dass diese Routineaufgabe in C++ solche Kopfschmerzen bereitet

    – wfbarksdale

    8. September 2011 um 5:05 Uhr

  • Es ist kein Kopfzerbrechen in C++ – es gibt verschiedene Möglichkeiten, dies zu erreichen. Programmierer kennen c++ weniger als c# – es geht um Marketing und Investitionen … siehe hier für verschiedene C++-Optionen, um dasselbe zu erreichen: cplusplus.com/faq/sequences/strings/split

    – hB0

    31. Oktober 2013 um 0:10 Uhr


  • @hB0 viele Fragen und Antworten durchzugehen und sich immer noch nicht zu entscheiden, was bedeutet, bereitet Kopfschmerzen. Der eine braucht diese Bibliothek, der andere ist nur für Leerzeichen, der andere behandelt keine Leerzeichen.

    – Paschalis

    14. April 2016 um 17:02 Uhr

  • Mögliches Duplikat von Split a string in C++?

    – KOB

    8. Mai 2017 um 19:16 Uhr

  • Warum muss alles in C++ ein Kampf sein?

    – Wael Assaf

    13. August 2019 um 10:26 Uhr


Wie tokenisiere ich einen String in C
Adam Pierc

Hier ist eine ganz einfache:

#include <vector>
#include <string>
using namespace std;

vector<string> split(const char *str, char c=" ")
{
    vector<string> result;

    do
    {
        const char *begin = str;

        while(*str != c && *str)
            str++;

        result.push_back(string(begin, str));
    } while (0 != *str++);

    return result;
}

  • muss ich einen Prototyp für diese Methode in der .h-Datei hinzufügen?

    – Suhrob Samjew

    22. Dezember 2011 um 8:26 Uhr


  • Dies ist nicht gerade die “beste” Antwort, da immer noch ein Zeichenfolgenliteral verwendet wird, bei dem es sich um das einfache C-Konstantenzeichenarray handelt. Ich glaube, der Fragesteller hat gefragt, ob er einen C++-String tokenisieren könnte, der vom Typ “String” ist, der von letzterem eingeführt wurde.

    – Vijay Kumar Kanta

    19. April 2017 um 7:05 Uhr

  • Dies erfordert eine neue Antwort, da ich stark vermute, dass die Aufnahme regulärer Ausdrücke in C ++ 11 die beste Antwort geändert hat.

    – Allmächtig

    25. Oktober 2017 um 15:45 Uhr

  • Zu dieser Antwort haben Sie Probleme mit Zeichenfolgen, bei denen das erste/letzte Zeichen gleich dem Trennzeichen ist. zB ergibt sich der String “a”. [” “, “a”].

    – y30

    13. November 2020 um 11:26 Uhr


  • Leider ist Boost nicht immer für alle Projekte verfügbar. Ich muss nach einer Nicht-Boost-Antwort suchen.

    – FuzzyBunnySlippers

    20. Dezember 2013 um 21:00 Uhr

  • Nicht jedes Projekt ist offen für „Open Source“. Ich arbeite in stark regulierten Branchen. Es ist wirklich kein Problem. Es ist einfach eine Tatsache des Lebens. Boost ist nicht überall verfügbar.

    – FuzzyBunnySlippers

    20. Dezember 2013 um 23:19 Uhr

  • @NonlinearIdeas Die andere Frage / Antwort bezog sich überhaupt nicht auf Open Source-Projekte. Dasselbe gilt für irgendein Projekt. Das heißt, ich verstehe natürlich eingeschränkte Standards wie MISRA C, aber dann versteht es sich, dass Sie sowieso alles von Grund auf neu erstellen (es sei denn, Sie finden zufällig eine kompatible Bibliothek – eine Seltenheit). Wie auch immer, der Punkt ist kaum, dass „Boost nicht verfügbar ist“ – es ist fast so, dass Sie spezielle Anforderungen haben irgendein allgemeine Antwort wäre ungeeignet.

    – Konrad Rudolf

    21. Dezember 2013 um 10:46 Uhr

  • @NonlinearIdeas Beispiel: Die anderen Nicht-Boost-Antworten sind ebenfalls nicht MISRA-konform.

    – Konrad Rudolf

    21. Dezember 2013 um 10:47 Uhr

  • @Dmitry Was ist “STL barf”?! Und die gesamte Community ist sehr dafür, den C-Präprozessor zu ersetzen – tatsächlich gibt es Vorschläge dazu. Aber Ihr Vorschlag, stattdessen PHP oder eine andere Sprache zu verwenden, wäre ein großer Rückschritt.

    – Konrad Rudolf

    11. September 2016 um 17:43 Uhr

1647286812 720 Wie tokenisiere ich einen String in C
Benutzer35978

Ein weiterer schneller Weg ist die Verwendung getline. Etwas wie:

stringstream ss("bla bla");
string s;

while (getline(ss, s, ' ')) {
 cout << s << endl;
}

Wenn Sie möchten, können Sie eine einfache machen split() Methode, die a zurückgibt vector<string>was wirklich nützlich ist.

  • Ich hatte Probleme mit dieser Technik mit 0x0A-Zeichen in der Zeichenfolge, wodurch die While-Schleife vorzeitig beendet wurde. Ansonsten ist es eine schöne einfache und schnelle Lösung.

    –Ryan H.

    24. Januar 2011 um 23:00 Uhr


  • Das ist gut, aber man muss nur bedenken, dass dabei das Standardtrennzeichen ‘\n’ nicht berücksichtigt wird. Dieses Beispiel funktioniert, aber wenn Sie etwas wie verwenden: while(getline(inFile,word,’ ‘)) wobei inFile ein ifstream-Objekt ist, das mehrere Zeilen enthält, erhalten Sie lustige Ergebnisse.

    – Hackrock

    19. Juni 2012 um 21:28 Uhr

  • Es ist zu schade, dass getline den Stream und nicht den String zurückgibt, wodurch es in Initialisierungslisten ohne temporäre Speicherung unbrauchbar wird

    – fuzzyTew

    3. August 2013 um 12:34 Uhr

  • Cool! Kein Boost und C++11, eine gute Lösung für die alten Projekte da draußen!

    – Deqing

    30. April 2014 um 7:09 Uhr

  • DAS ist die Antwort, der Name der Funktion ist nur etwas umständlich.

    – Nils

    1. Juni 2019 um 21:31 Uhr

1647286812 192 Wie tokenisiere ich einen String in C
Kennzeichen

Verwenden Sie strtok. Meiner Meinung nach besteht keine Notwendigkeit, eine Klasse um das Tokenisieren herum zu erstellen, es sei denn, strtok bietet Ihnen nicht das, was Sie brauchen. Vielleicht nicht, aber in mehr als 15 Jahren des Schreibens verschiedener Parsing-Codes in C und C++ habe ich immer strtok verwendet. Hier ist ein Beispiel

char myString[] = "The quick brown fox";
char *p = strtok(myString, " ");
while (p) {
    printf ("Token: %s\n", p);
    p = strtok(NULL, " ");
}

Ein paar Vorbehalte (die möglicherweise nicht Ihren Anforderungen entsprechen). Der String wird dabei “zerstört”, dh EOS-Zeichen werden inline in die Trennzeichen gesetzt. Bei korrekter Verwendung müssen Sie möglicherweise eine nicht konstante Version der Zeichenfolge erstellen. Sie können auch die Liste der Trennzeichen während der Analyse ändern.

Meiner Meinung nach ist der obige Code viel einfacher und einfacher zu verwenden, als eine separate Klasse dafür zu schreiben. Für mich ist dies eine dieser Funktionen, die die Sprache bietet, und sie macht es gut und sauber. Es ist einfach eine “C-basierte” Lösung. Es ist angemessen, es ist einfach und Sie müssen nicht viel zusätzlichen Code schreiben 🙂

  • Ich hatte Probleme mit dieser Technik mit 0x0A-Zeichen in der Zeichenfolge, wodurch die While-Schleife vorzeitig beendet wurde. Ansonsten ist es eine schöne einfache und schnelle Lösung.

    –Ryan H.

    24. Januar 2011 um 23:00 Uhr


  • Das ist gut, aber man muss nur bedenken, dass dabei das Standardtrennzeichen ‘\n’ nicht berücksichtigt wird. Dieses Beispiel funktioniert, aber wenn Sie etwas wie verwenden: while(getline(inFile,word,’ ‘)) wobei inFile ein ifstream-Objekt ist, das mehrere Zeilen enthält, erhalten Sie lustige Ergebnisse.

    – Hackrock

    19. Juni 2012 um 21:28 Uhr

  • Es ist zu schade, dass getline den Stream und nicht den String zurückgibt, wodurch es in Initialisierungslisten ohne temporäre Speicherung unbrauchbar wird

    – fuzzyTew

    3. August 2013 um 12:34 Uhr

  • Cool! Kein Boost und C++11, eine gute Lösung für die alten Projekte da draußen!

    – Deqing

    30. April 2014 um 7:09 Uhr

  • DAS ist die Antwort, der Name der Funktion ist nur etwas umständlich.

    – Nils

    1. Juni 2019 um 21:31 Uhr

1647286813 95 Wie tokenisiere ich einen String in C
KeithB

Sie können Streams, Iteratoren und den Kopieralgorithmus verwenden, um dies ziemlich direkt zu tun.

#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>

int main()
{
  std::string str = "The quick brown fox";

  // construct a stream from the string
  std::stringstream strstr(str);

  // use stream iterators to copy the stream to the vector as whitespace separated strings
  std::istream_iterator<std::string> it(strstr);
  std::istream_iterator<std::string> end;
  std::vector<std::string> results(it, end);

  // send the vector to stdout.
  std::ostream_iterator<std::string> oit(std::cout);
  std::copy(results.begin(), results.end(), oit);
}

  • Ich finde diese std:: irritierend zu lesen. Warum nicht “using” verwenden?

    – Benutzer35978

    28. November 2008 um 4:19 Uhr

  • @Vadi: weil das Bearbeiten des Beitrags eines anderen ziemlich aufdringlich ist. @pheze: Ich lasse das lieber std So weiß ich, wo mein Objekt herkommt, das ist nur eine Frage des Stils.

    – Matthias M.

    2. April 2010 um 8:49 Uhr

  • Ich verstehe Ihren Grund und denke, dass es eigentlich eine gute Wahl ist, wenn es für Sie funktioniert, aber aus pädagogischer Sicht stimme ich pheze tatsächlich zu. Es ist einfacher, ein völlig fremdes Beispiel wie dieses mit einem “using namespace std” oben zu lesen und zu verstehen, weil es weniger Aufwand erfordert, die folgenden Zeilen zu interpretieren … besonders in diesem Fall, weil alles aus der Standardbibliothek stammt. Sie können es leicht lesbar und offensichtlich machen, woher die Objekte kommen, indem Sie eine Reihe von “using std::string;” usw. Zumal die Funktion so kurz ist.

    – Cheshirekow

    16. Juli 2010 um 11:27 Uhr

  • Obwohl die „std::“-Präfixe irritierend oder hässlich sind, ist es am besten, sie in den Beispielcode aufzunehmen, damit klar ist, woher diese Funktionen kommen. Wenn sie Sie stören, ist es trivial, sie durch ein »using« zu ersetzen, nachdem Sie das Beispiel gestohlen und für sich beansprucht haben.

    – dlkammern

    11. April 2012 um 14:54 Uhr

  • ja! was er sagte! Best Practices ist die Verwendung des std-Präfixes. Jede große Codebasis wird zweifellos ihre eigenen Bibliotheken und Namespaces haben, und die Verwendung von “using namespace std” wird Ihnen Kopfschmerzen bereiten, wenn Sie anfangen, Namespace-Konflikte zu verursachen.

    – Mich

    18. Juli 2012 um 17:08 Uhr

1002930cookie-checkWie tokenisiere ich einen String in C++?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy