[C++]Als 'string' deklarierte Funktion gibt kein Array zurück

F

Fabian H

Hi C++ler,
ich hoffe, dass ich das Topic richtig getroffen hab...

Zum Problem:
Ich wollte mir für die C++ Klasse string eine split Funktion schreiben, da diese so etwas offensichtlich ja nicht besitzt.

Die Funktion an sich klappt prima, nur gibt es das Problem, dass der Compiler meckert, wenn ich aus der Funktion, die als string deklariert (wenn man das so sagt) ist, ein String Array zurückgeben will (string sRetArr[a_iNum];).

Hier der Code (strc ist eine Funktion von mir, die die Anzahl eines bestimmten Zeichens in einem String zurückgibt):
Code:
string split( string a_sInput, char a_cSplit, int &a_iNum )
{
    a_sInput += a_cSplit;
    a_iNum = strc(a_sInput, a_cSplit);
    string sRetArr[a_iNum];
    int iLastPos = 0, iCount = 0;

    for (int i=0; i<a_sInput.size(); i++) {
        if (a_sInput.at(i) == a_cSplit) {
            sRetArr[iCount] = a_sInput.substr(iLastPos, i-iLastPos);
            iLastPos = i + 1;
            iCount++;
        }
    }

    return sRetArr;
}

Der Compiler (gcc/Dev C++) gibt folgenden Fehler aus:
31 main.cpp
conversion from `basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> > *' to non-scalar type `string' requested

Zeile 31 ist die return-Anweisung.

Ich hoffe ihr könnt mir helfen. Danke.
 
Wenn Du sRetArr mit string sRetArr[a_iNum]; deklarierst ist sRetArr natürlich ein Zeiger auf das erste Element des Arrays, von daher solltest Du probieren als Funktions-Rückgabetyp string* zu benutzen.
Weiterhin solltest Du, da du ja ein Array zurückgeben willst, dieses dann auch dynamisch oder statisch anlegen, da sonst nach Verlassen der Funktion der Speicherbereich im Stack wieder freigegeben wird und das Array nicht mehr im Speicher vorliegt.

Ob das mit string so funktioniert kann ich nur erahnen, da string als template behandelt wird.
 
Code:
string* split( string a_sInput, char a_cSplit, int &a_iNum )
{
    a_sInput += a_cSplit;
    a_iNum = strc(a_sInput, a_cSplit);
    string* sRetArr = new string[a_iNum];
    int iLastPos = 0, iCount = 0;

    for (int i=0; i<a_sInput.size(); i++) {
        if (a_sInput.at(i) == a_cSplit) {
            sRetArr[iCount] = a_sInput.substr(iLastPos, i-iLastPos);
            iLastPos = i + 1;
            iCount++;
        }
    }

    return sRetArr;
}
versuchs mal so ;-) nich vergessen das dein progy das array später deleten muss...

String ist eine template-class... und nachdem das template expanded worden is, verhält sie sich wie eine normale klasse... entsprechend ganz einfach n pointer auf das array zurück gegeben...
und ein array das du zurückgibts darf niemals, aber auch niemals auf der funktion alloziert sein die es zurückgibt, --> das nennt man sonst zur laufzeit 0xC0000005 oder anders ausgedrück AccessViolation
Also allozier sowas lieber auf dem Heap.
 
Danke euch beiden!
(Ich glaub, ich sollte C++ doch mal ein bisschen gründlicher lernen :) )

@chibisuke:
nich vergessen das dein progy das array später deleten muss...
Meinst du damit ungefär das hier?
Code:
string *aMeinArray = split("s,t,r,i,n,g", ',', iAnz);
//Code ...
delete aMeinArray;
 
Also nur mal so am Rande, wenn du schon den Typ String der STL verwendest, warum verwendest du dann nicht auch den Type vector?.
Also Beispiel:
Code:
int SplitString(string data, char delimiter, vector<string> *arr)
{
	string item = "";
	arr->clear();
	int length = data.length();

	for(int i=0; i<length; i++)
	{
		if(data[i] != delimiter)
		{	
			item += data[i];
		}
		else
		{
			arr->push_back(item);
			item = "";
		}
	}
	if(!item.empty())
		arr->push_back(item);
	
	int size = arr->size();
	return size;
}
Das nur mal so als Anregung.

Gruss Homer
 
Ah ja :)

Ich glaub ich lass es erstmal bei meiner, für mich verstandlichen, Funktion.
Vielleicht kapier ich ja deinen Code irgendwann mal :)
 
stimmt,,,, natürlich mit [],... darauf hab ich gar nicht geachtet gehabt, aber im endeffekt ists bei aktuellen betriebssystemen eh egal ;-) wenns nicht grad n fastcgi app is oder so, dann wird der benutzer das programm zwangsläufig auch wieder beenden, und damit wird von windows automatisch aller belegter speicher freigegeben, das gillt für win2k und XP bei NT weiß ichs net, aber ich glaub auch...
 
das ist auch bie Windows 95 und 98 so (solang eine 32 Bit applikation), aber trotzdem hast du memory leaks wenn dein programm länger läuft bzw. die Funktion öfters aufruft

wird die Funktion nur einmal im programm durchgeführt (und danach beendet) dann macht das windows selber aber gesund ist das trotzdem nicht, und guter stil erst recht nicht (sowas sollte man sich nicht angewöhnen)
 

Neue Beiträge

Zurück