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;
}