Split Funktion

S

spex

Moinsen,

Hab mir folgende Split-Funktion unter Linux geschrieben:
PHP:
string *split(string data, string delimeter, int count = 0)
{
    string *arg;
    
    if( count > 0 )
    {
        arg = (string *) malloc(count * sizeof(string) );
       
    }else
    {
        count = strcnt(data, delimeter);
        arg = (string *) malloc(count * sizeof(string) );
    }
    arg = new string[count+1];

    int pos = 0;
    
    for(int i = 0; i <= count; i++)
    {
        pos = data.find(delimeter);
        arg[i] = data.substr(0, pos);
        data = data.substr(pos+delimeter.length(), data.length());
    }

    return arg;
}

Funktioniert auch einwandfrei, ist aber so eine kleine Übung gewesen in Sachen String-Funktionen und Arrays, die ich mir habe einfallen lassen, da ich im Internet keine vernünftige Split-Funktion habe finden können.

Hat nun jmd. von euch Verbesserungsvorschläge oder gar etwas an der Art und Weise auszusetzen wie ich es geschrieben habe, dann bitte melden. Ich lerne aus Fehlern.

Gruß sp3x
 
Hi

im oberen Teil reservierst du mit malloc Speicher und direkt nach der If-Anweisung nochmal mit new, dabei benutzt du 2mal den gleichen Pointer.

lg
 
Du gibst den Zeiger mit dem alloziertem Speicherbereich einfach zurück, ohne dafür zu sorgen das der Speicherbereich in irgendeiner weise, wenigstens am Ende vom Programm, freigegeben wird: Speicherleck.

Was du noch machen könntest, wäre die Funktion strtok für die Funktion string nachzuschreiben ( entweder benutzt du dabei strtok mit chars oder machst sie ganz neu ;).
 
Ha das mit dem Speicher ist mir nicht aufgefallen bzw hab ich vergesen zu entfernen.
Hab es dort halt mit beiden Methoden versucht und immer eine auskommentiert.

Werd eure Vorschläge heute Nachmitteag nach der Arbeit umsetzen.

Danke schonmal für die Hinweise

Ergänzung: Die Funktion strcnt zählt das Vorkommen aller Delimeter in einem String.
PHP:
int strcnt(string data, string search)
{
    int count = 0, pos;
    
    for(int i = 0; !i;)
    {
        pos = data.find(search);
        
        if( pos >= 0 )
        {
            count++;
            data = data.substr(pos+search.length(), data.length());
        }else
        {
            i++;
        }
    }
    
    return count;
}
 
Zuletzt bearbeitet von einem Moderator:
Hab die Funktion jetzt noch schnell umgeschrieben. Konnte noch etwas zusammenfassen. Aber bekomme jetzt
Code:
/usr/share/netbeans/cnd2/bin/dorun.sh: line 103: 12661 Speicherzugriffsfehler  "$pgm" "$@"

Der Aufruf sieht so aus, ohne das ich den Rückgabewert in einer Variable Speichere.
Code:
split("Hallo wie gehts?", " ");

Die Funktion:
Code:
string *split(string data, string delimeter, int count = 0)
{
    string *arg;
    
    if( !count )
    {
        count = strcnt(data, delimeter);
        string arg[count + 1];
    }
    
    arg = new string[count + 1];
    
    for(int i, pos = 0; i <= count; i++)
    {
        pos = data.find(delimeter);
        arg[i] = data.substr(0, pos);
        data = data.substr(pos+delimeter.length(), data.length());
    }
    
    return arg;
    delete arg; // Obwohl ich bezweifle das es nach dem Return noch zur Ausführung kommt
                      // Hab aber keine Zeit jetzt nachzuguggn das mach ich nachher.
    
}
 
Zuletzt bearbeitet von einem Moderator:
Hi

das delete nach return, wird natürlich nicht mehr ausgeführt. Aber sollte doch auch nicht das Problem sein, wenn der Speicher erst in der Aufrufenden-Funktion freigegeben wird.

Als Alternative könntest du nen std::list<std::string> Objekt zurückgegeben.


und zu new:

new -> delete
new[] -> delete[]

lg
 
Die Funktion sieht jetzt folgendermaßen aus, und funktioniert auch hervoragend!
Code:
string *split(string data, string delimeter, int count = 0)
{
    
    if( !count )
    {
        count = strcnt(data, delimeter);
    }
    
    string *arg = new string[count + 1];
    
    for(int i = 0, pos = 0; i <= count; i++)
    {
        pos = data.find(delimeter);
        arg[i] = data.substr(0, pos);
        data = data.substr(pos+delimeter.length(), data.length());
    }
    
    return arg;    
}

// ///////////////////////////////////////////////
int strcnt(string data, string search)
{
    int count = 0, pos;
    
    for(int i = 0; !i;)
    {
        pos = data.find(search);
        
        if( pos >= 0 )
        {
            count++;
            data = data.substr(pos+search.length(), data.length());
        }else
        {
            i++;
        }
    }
    
    return count;
}
 
Guck mal nen bissel weiter oben (im Forum) ... da steht auch ne implementierung die um einiges schneller sein dürfte.
 
Hallo,

Leider ist diese Splitfunktion Warning-behaftet, ich bügel das mal aus!

Code:
------ Erstellen gestartet: Projekt: navigationapp, Konfiguration: Debug Win32 ------
Kompilieren...
graph.cpp
d:\hiwi\navigationapp\navigationapp\stringtools.h(25) : warning C4267: '=': Konvertierung von 'size_t' nach 'int', Datenverlust möglich
d:\hiwi\navigationapp\navigationapp\stringtools.h(40) : warning C4267: '=': Konvertierung von 'size_t' nach 'int', Datenverlust möglich

Hier die warnung-free version:

Code:
	static string *split(string data, string delimeter, int count = 0)
		{
		    
			if( !count )
			{
				count = strcnt(data, delimeter);
			}
		    
			string *arg = new string[count + 1];
		    
			for(int i = 0; i <= count; i++)
			{

				size_t pos = data.find(delimeter);
				arg[i] = data.substr(0, pos);
				data = data.substr(pos+delimeter.length(), data.length());
			}
		    
			return arg;    
		}

// ///////////////////////////////////////////////
	static int strcnt(string data, string search)
	{
		int count = 0;
		size_t pos;
	    
		for(int i = 0; !i;)
		{
			pos = data.find(search);
	        
			if( pos >= 0 )
			{
				count++;
				data = data.substr(pos+search.length(), data.length());
			}else
			{
				i++;
			}
		}
	    
		return count;
	}
 
Zuletzt bearbeitet:
Und eine bessere Lösung stand dennoch im Thread, der zum damaligen Zeitpunkt genau über diesem in der Übersicht gelistet war.
 
Zurück