namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


howto:split_string
no way to compare when less than two revisions

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


howto:split_string [2020-07-27 09:36] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Text mit Trennfolgen zergliedern ======
 +> // Teach a man to fish and you feed him for a lifetime. //
 +> // Unless he doesn't like sushi -- then you also have to teach him to cook. //
 +>> --- http://www.stackoverflow.com/questions/1581839/whats-the-mechanism-of-sizeof-in-c-c
 +===== Aufgabe =====
 +Eine Textzeichenkette ist in eine Folge von Teilen zu zerlegen, 
 +zwischen denen jeweils eine feststehende Zeichenfolge zu finden ist.
 +Aus
 +  "1, 2, 3, 4, 5"    
 +werden mit der Trennzeichenfolge ", " die 5 Teilketten
 +  "1", "2", "3", "4", "5".
 +Die gewünschte Funktion ''split(text, separator)'' nimmt ein Leerzeichen als Standardtrenner.  
 +===== Ein Ansatz in C++98 =====
 +<code cpp split.cpp>
 +#include <string>
 +#include <vector>
 +
 +std::vector<std::string> 
 +split(std::string const& input, std::string const& separator = " ")
 +{
 +  std::vector<std::string> result;
 +  std::string::size_type position, start = 0;
 +
 +  while (std::string::npos != (position = input.find(separator, start)))
 +  {
 +    result.push_back(input.substr(start, position-start));
 +    start = position + separator.size();
 +  }
 +
 +  result.push_back(input.substr(start));
 +  return result;
 +}
 +</code>
 +Eine [[http://stackoverflow.com/questions/236129/split-a-string-in-c|Anzahl weiterer Lösungen]] findet sich auf Stackoverflow.
 +Für einzelne Separatorzeichen aus einer Liste vgl. http://rosettacode.org/wiki/Tokenize_a_string#C.2B.2B .
 +
 +===== Leichtgewichtiger in C++17 =====
 +Das Kopieren von Zeichenketten ist aufwendig. 
 +Mit [[kennen:include:string_view|std::string_view]] wird jeweils nur ein Zeiger auf den Anfang und die Länge gespeichert.
 +Voraussetzung ist, dass die zu zerlegende Teilzettenkette mindestens solange existiert, wie per ''string_view'' darauf zugegriffen wird:
 +<code cpp split_sv.cpp>
 +#include <string_view> // C++17
 +#include <vector>
 +
 +auto split(std::string_view input, std::string_view separator = " ")
 +{
 +  std::vector<std::string_view> result;
 +  std::string_view::size_type position, start = 0;
 +
 +  while (std::string_view::npos != (position = input.find(separator, start)))
 +  {
 +    result.push_back(input.substr(start, position-start));
 +    start = position + separator.size();
 +  }
 +
 +  result.push_back(input.substr(start));
 +  return result;
 +}
 +</code>
 +Hier wird eine ganze Zeichenkette als Trenner erwartet.
 +In diesem Beispiel werden die Zeichenfolgen ", " 
 +der Eingabe ''1, 2, 3, 4, 5'' als Trenner akzeptiert,
 +ein einzelnes Komma jedoch nicht:
 +<code cpp>
 +#include <iostream>
 +
 +int main()
 +{
 +  std::string line;
 +  while (std::getline(std::cin, line))
 +  {
 +    for (auto part : split(line, ", ")) // C++11
 +    {
 +      std::cout << "\'" << part << "\'\n";
 +    }
 +  }
 +  return 0;
 +}
 +</code>
 +
 +===== Reguläre Ausdrücke als Trenner =====
 +[[kennen:include:regex|Reguläre Ausdrücke]] geben mehr Möglichkeiten zur Beschreibung des Trenners. 
 +Hier eine C++17-Variante mit ''string_view'':
 +<code cpp split_regex_sv.cpp>
 +#include <iostream>
 +#include <regex>
 +#include <string_view>
 +
 +// adapted from: http://stackoverflow.com/a/28142357/831725
 +
 +auto split(std::string_view input, std::string_view separator = "\\s+"
 +{
 +    std::vector<std::string_view> result;
 +    std::regex rex(separator.begin(), separator.end());
 +    std::cregex_token_iterator iter(input.begin(), input.end(), rex, -1);
 +    std::cregex_token_iterator end;
 +                             // -1 : get stuff not matched by regex
 +    for (; iter != end; ++iter)  
 +    {
 +        std::string_view::size_type numchars = iter->second - iter->first; 
 +        result.push_back({iter->first, numchars});
 +    }
 +    return result;
 +}
 +
 +int main()
 +{
 +    for (auto e : split("eins   zwei drei    "))  // Whitespaces als Trenner
 +    {
 +        std::cout << e << '\n';
 +    }
 +
 +    for (auto e : split("vier|fuenf:sechs,sieben", "[|:,]")) 
 +    {  
 +        std::cout << e << '\n';
 +    }
 +}
 +</code> 
  
howto/split_string.txt · Zuletzt geändert: 2020-07-27 09:36 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki