Możesz użyć tej std::string::find()
funkcji, aby znaleźć pozycję ogranicznika łańcucha, a następnie użyć, std::string::substr()
aby uzyskać token.
Przykład:
std::string s = "scott>=tiger";
std::string delimiter = ">=";
std::string token = s.substr(0, s.find(delimiter)); // token is "scott"
find(const string& str, size_t pos = 0)
Funkcja zwraca pozycję pierwszego wystąpienia str
w ciągu, lub npos
jeśli ciąg nie zostanie znaleziony.
substr(size_t pos = 0, size_t n = npos)
Zwraca fragment obiektu, począwszy od położenia pos
i długości npos
.
Jeśli masz wiele ograniczników, po wyodrębnieniu jednego tokena możesz go usunąć (w tym ogranicznik), aby kontynuować wyodrębnianie (jeśli chcesz zachować oryginalny ciąg, po prostu użyj s = s.substr(pos + delimiter.length());
):
s.erase(0, s.find(delimiter) + delimiter.length());
W ten sposób możesz łatwo zapętlić się, aby zdobyć każdy token.
Kompletny przykład
std::string s = "scott>=tiger>=mushroom";
std::string delimiter = ">=";
size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
token = s.substr(0, pos);
std::cout << token << std::endl;
s.erase(0, pos + delimiter.length());
}
std::cout << s << std::endl;
Wynik:
scott
tiger
mushroom
size_t last = 0; size_t next = 0; while ((next = s.find(delimiter, last)) != string::npos) { cout << s.substr(last, next-last) << endl; last = next + 1; } cout << s.substr(last) << endl;
mushroom
wyjścia poza pętlę, tj.s = mushroom
std::string token = s.substr(s.find(delimiter) + 1);
, jeśli jesteś pewien, że istnieje (używam +1 w długości) ...Ta metoda wykorzystuje
std::string::find
bez mutowania oryginalnego ciągu przez zapamiętywanie początku i końca poprzedniego tokenu podciągowego.źródło
Możesz użyć następnej funkcji do podzielenia łańcucha:
źródło
split("abc","a")
zwróci wektor lub pojedynczy ciąg,"bc"
w którym myślę, że byłoby bardziej sensowne, gdyby zwrócił wektor elementów["", "bc"]
. Używaniestr.split()
w Pythonie intuicyjnie było dla mnie zwracać pusty ciąg w przypadkudelim
znalezienia go na początku lub na końcu, ale to tylko moja opinia. W każdym razie myślę, że należy o tym wspomniećif (!token.empty())
problemu zapobiegającego wspomnianemu przez @kyriakosSt, a także innych problemów związanych z kolejnymi ogranicznikami.if (!token.empty())
go nie wydaje się wystarczające, aby go naprawić.Dla ogranicznika ciągu
Podziel ciąg na podstawie ogranicznika ciągu . Takich jak dzielenie łańcucha
"adsf-+qwret-+nvfkbdsj-+orthdfjgh-+dfjrleih"
na podstawie ogranicznika łańcucha"-+"
, wyjście będzie{"adsf", "qwret", "nvfkbdsj", "orthdfjgh", "dfjrleih"}
Wynik
Dla separatora jednoznakowego
Podziel ciąg na podstawie ogranicznika znaków. Takich jak rozszczepiania łańcucha
"adsf+qwer+poui+fdgh"
z separatorem"+"
pokaże na wyjściu{"adsf", "qwer", "poui", "fdg"h}
Wynik
źródło
vector<string>
, myślę, że to wywoła konstruktora kopiowania.Ten kod dzieli linie z tekstu i dodaje wszystkich do wektora.
Nazwany przez:
źródło
vector<string> split(char *phrase, const string delimiter="\n")
strtok pozwala na przekazywanie wielu znaków jako ograniczników. Założę się, że jeśli podałeś "> =", twój przykładowy ciąg zostałby poprawnie podzielony (nawet jeśli> i = są liczone jako oddzielne separatory).
EDYCJA, jeśli nie chcesz używać
c_str()
do konwersji z łańcucha na char *, możesz użyć substr i find_first_of do tokenizacji .źródło
strtok()
ponieważ wymagałoby to użycia tablicy char zamiast łańcucha..c_str()
jest również tanie i łatwe.Oto moje zdanie na ten temat. Obsługuje przypadki krawędzi i przyjmuje opcjonalny parametr, aby usunąć puste wpisy z wyników.
Przykłady
źródło
Powinno to działać idealnie dla ograniczników ciągów (lub pojedynczych znaków). Nie zapomnij dołączyć
#include <sstream>
.Pierwsza pętla while wyodrębnia token za pomocą pierwszego znaku ogranicznika łańcucha. Druga pętla while pomija resztę separatora i zatrzymuje się na początku następnego tokena.
źródło
Chciałbym użyć
boost::tokenizer
. Oto dokumentacja wyjaśniająca, jak wykonać odpowiednią funkcję tokenizera: http://www.boost.org/doc/libs/1_52_0/libs/tokenizer/tokenizerfunction.htmOto taki, który działa w twoim przypadku.
źródło
Odpowiedź już tam jest, ale wybrana odpowiedź używa funkcji wymazywania, która jest bardzo kosztowna, pomyśl o bardzo dużym ciągu znaków (w MB). Dlatego używam funkcji poniżej.
źródło
string.split()
metodę Python .)Jest to kompletna metoda, która dzieli ciąg na dowolny ogranicznik i zwraca wektor pociętych ciągów.
Jest to adaptacja odpowiedzi od ryanbwork. Jednak jego sprawdzanie:
if(token != mystring)
daje nieprawidłowe wyniki, jeśli masz powtarzające się elementy w swoim ciągu. To jest moje rozwiązanie tego problemu.źródło
while (true)
jest zwykle przerażające, gdy widzi się taki fragment kodu. Osobiście polecam przepisać to tak, aby porównaniestd::string::npos
(lub odpowiednio porównanie zmystring.size()
) sprawiło, żewhile (true)
przestarzała.Jeśli nie chcesz modyfikować łańcucha (jak w odpowiedzi Vincenzo Pii) i chcesz również wypisać ostatni token, możesz użyć tego podejścia:
źródło
PS: Działa tylko wtedy, gdy długości ciągów po podziale są równe
źródło
Funkcjonować:
Testy jednostkowe:
źródło
źródło
źródło