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?
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?
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
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
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
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
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