Logo

C++ Builder: Split-Funktion um einen String anhand von Trennzeichen zu zerlegen

Ab und zu möchte man einen String anhand eines Trennzeichens teilen und mit den extrahierten Stücken weiterarbeiten. Ich nutze diese Möglichkeit z.B. gerne für die Auswertung von verketteten Programm-Aufrufparametern. Viele Frameworks bieten hierfür eine fertige Funktion an. Ich könnte jetzt auch einfach gebetsmühlenartig auf boost verweisen, aber nicht jeder mag für so eine kleine Hilfsfunktion gleich einen riesigen Overhead in sein Projekt blasen.

Ich habe folgende Funktion in etwas anderer Form im Netz gefunden und diese noch etwas aufgebohrt. Der Rückgabewert der Funktion enthält die Anzahl der Tokens bzw. 0 bei einem Fehler. Die Tokens selbst werden in die per Zeiger übergebene TStringList gespeichert und können so direkt weiter verarbeitet werden.
Wie immer dokumentiere ich in englisch und benutze den JavaDoc-Style. Die Funktion eignet sich gut für kurze Texte, eine 200-seitige Textdatei würde ich damit aber nicht unbedingt parsen.

/**
 * Function to split a String by a separator (like 'explode' in PHP)
 *
 * @author Bjoern Bastian
 * @version 20120927
 * @param string The content we want to split
 * @param string The divider
 * @param stringlist Pointer to a StringList for the tokens
 * @param boolean Trim the content
 * @return integer Length of the StringList or 0
 */
int Explode(String sContent, String sSeparator, TStringList *slTokens, 
bool bTrim = true)
{
  // abort if no stringlist is given
  if (slTokens == NULL) { return 0; }
  // trim the content
  if (bTrim) { sContent = sContent.Trim(); }
 
  // go through the content and split it like Moses split the Red Sea
  while (sContent.Length() > 0)
  {
    // find first separator in content
    int iPos = sContent.Pos(sSeparator);
    if (iPos > 0)
    {
      // insert front/first part of content into stringlist
      slTokens->Add(sContent.SubString(0, iPos - 1));
      // shorten the content to the rest
      sContent = sContent.SubString(iPos + 1, sContent.Length() - iPos);
      // trim the content
      if (bTrim) { sContent = sContent.Trim(); }
    }
    else
    {
      // just one token left
      slTokens->Add(sContent);
      // abort the loop with empty content
      sContent = "";
    }
  }
  return slTokens->Count;
}

Hier ein Beispiel zur Anwendung. Als Trennzeichen wurde der Pipe | benutzt.

TStringList *slTokens = new TStringList();
try
{
  // get the tokens
  Explode(L"Token1|Token2|Token3", "|", slTokens, true);
 
  // go through the stringlist
  for (int i = 0; i < slTokens->Count; i++)
  {
    //do something with slTokens->Strings[i]
    wprintf((slTokens->Strings[i]+"\n").c_str());
  }
}
__finally
{
  // release object memory
  delete slTokens;
  slTokens = NULL;
}

 



Sag deine Meinung