# String zerteilen und in Array ablegen



## Bifix (10. Januar 2005)

Hallo,

      ich habe ein Problem. Und zwar:

 Wie kann ich einen String, der folgenden Aufbau hat: "2;3;55;12;324;" so zerlegen, dass ich ihn in einem Array von Integer ablegen kann?

      Der String kann aber beliebig groß seine. (z.B. Das erste Mal 5 Werte und das zweite Mal 10 Werte) 

      Das Array muss also dynamisch erstellt werden!

      Könnt ihr mir helfen?

      Danke 

      mfg
      Bifix


----------



## Beichtpfarrer (10. Januar 2005)

Schnellsuche - "dynamisches Array"
und die Zerlegung sollte ja kein Problem sein....


----------



## Bifix (10. Januar 2005)

Hallo,

 doch gerade das zerlegen vom string bereitet mir Probleme. Wie bekomme ich die ";" daraus?

 Oder anderes Problem: 

 In jeder Zeile einer Datei steht eine Zahl! Wie kann ich jede dieser Zahlen in ein Array einlesen bis zum Ende der Datei?

 Bifix


----------



## svebert (3. April 2005)

Ich habe genau das gleiche Problem, nur dass ich noch nicht einmal weiß, wie ich ein dynamisches Array deklarieren soll und es dann zu laufzeit vergrößern soll. Kann mir jemand helfen?
Das zerteilen des Strings würde ich so machen, dass ich mit der funktion string.c_str aus dem string ein char mache mit der größe string.length. Dann würde ich mit einer schleife jedes Element des Char-Arrays abfrage, ob es ein komma ist oder nicht und damit das Dynamische Array füllen. (Wenn ich wüsste, wie ich ein Array zur laufzeit vergrößere).


----------



## Mr.Undertaker (3. April 2005)

Zum Thema "dynamisches Array":

Also eine verkettete Liste würde hier weiterhelfen.
Programmiert ihr in C++, so benutzt einfach den *std::vector* 
aus der STL. (Ist eine Template-Klasse).
Da könnt ihr soviel hinten dran hängen wie ihr wollt.

@svebert
Machs nicht so umständlich ... gucks du hier:
Achtung, der code funktioniert nur richtig, wenn das letzte Zeichen ein
Semikolon ist.


```
#include <iostream>
#include <string>
#include <vector>

int main(void)
{
	std::string strTest;
	std::string strTemp;
	std::vector<int> vcInts;

	strTest = "20;30;40;50;60;";
	
	//lese string in vector
	strTemp.clear();
	for(int i=0;i<strTest.size();i++)
	{
		if(strTest[i]!=';') strTemp += strTest[i];
		else
		{
			int t = atoi(strTemp.c_str());  
			vcInts.push_back(t);
			strTemp.clear();
		}
	}

	//Lese den Inhalt des vectors aus
	std::vector<int>::iterator it;
	for(it = vcInts.begin(); it != vcInts.end(); it++)
	{
		std::cout<<"\nElement: "<<*it;
	}
	return 0;
}
```

Hoffe das hilft euch weiter. 

Gruß, Christian


----------



## svebert (4. April 2005)

Okay, vielen Dank. Das funktioniert gut.
Noch eine andere Frage (ich bin total neu in c++) :
Wie kann ich sagen, dass der Rückgabewert einer Funktion ein Vector ist?


```
std::vector<int> Meine_Funktion(int bla; bool blub)
{
   std::vector<int> MyVector;
   ...
   ...
   ...
   return MyVector;
}
```

So?
Mein Compiler akzeptiert das, sieht aber ein bisschen doof aus. hm

ABer es geht. Es geht gut! Super!
Vielen Dank


----------



## Mr.Undertaker (4. April 2005)

So gehts schon. Doof aussehen tuts auch nicht,
aber es gibt ein kleines "Effizienz Problem" : "return by value".
Du solltest den Rückgabe-Parameter als "return by reference" machen,
da wird der vector nicht im speicher "rumkopiert".

Da du ein Newbie bist, solltest vielleicht erst einmal ein paar
Tutorials über solche Themen lesen. Gleich die STL ist nicht
unbedingt so gut.

Habs schnell umgestellt:


```
#include <iostream>
#include <string>
#include <vector>

void func(std::string strTest, std::vector<int>& vcOut);

int main(void)
{
	std::string strTest;
	std::vector<int> vcVector;

	func("20;30;40;50;60;",vcVector);

	//Lese den Inhalt des vectors aus
	std::vector<int>::iterator it;
	for(it = vcVector.begin(); it != vcVector.end(); it++)
	{
		std::cout<<"\nElement: "<<*it;
	}
	return 0;
}

void func(std::string strTest, std::vector<int>& vcOut)
{
	std::string strTemp;
	
	//lese string in vector
	strTemp.clear();
	for(int i=0;i<strTest.size();i++)
	{
		if(strTest[i]!=';') strTemp += strTest[i];
		else
		{
			int t = atoi(strTemp.c_str());  
			vcOut.push_back(t);
			strTemp.clear();
		}
	}
}
```

Gruß,Christian


----------



## Kachelator (4. April 2005)

Mr.Undertaker hat gesagt.:
			
		

> So gehts schon. Doof aussehen tuts auch nicht,
> aber es gibt ein kleines "Effizienz Problem" : "return by value".
> Du solltest den Rückgabe-Parameter als "return by reference" machen,
> da wird der vector nicht im speicher "rumkopiert".
> ...




Die Lösung ist gut, aber manchmal ist es okay, so was per Wert zurückzugeben. Effizient ist es aber nicht, das ist wahr.

Was Effizienz anbelangt: Es wäre günstig, innerhalb der Funktion vor der Schleife die Größe des Vectors mittels resize() auf einen sinnvollen Wert zu setzen, anstatt innerhalb der Schleife auf ein automatisches (eventuell mehrfaches) Vergrössern und Umkopieren des Vectors zu setzen.

Oh, und der Vector sollte zu Beginn der Funktion eventuell geleert werden.


----------



## Mr.Undertaker (4. April 2005)

Kachelator hat gesagt.:
			
		

> Die Lösung ist gut, aber manchmal ist es okay, so was per Wert zurückzugeben. Effizient ist es aber nicht, das ist wahr.
> 
> Was Effizienz anbelangt: Es wäre günstig, innerhalb der Funktion vor der Schleife die Größe des Vectors mittels resize() auf einen sinnvollen Wert zu setzen, anstatt innerhalb der Schleife auf ein automatisches (eventuell mehrfaches) Vergrössern und Umkopieren des Vectors zu setzen.
> 
> Oh, und der Vector sollte zu Beginn der Funktion eventuell geleert werden.



Ich stimmte zu, ich stimme zu, ich stimme zu.  ;-)  ;-)  ;-)


----------



## Kachelator (4. April 2005)

Wenn man an einen Vector neue Einträge anhängt, ist irgendwann die Kapazität erschöpft. In dem Fall wird ein neuer, grösserer Speicherbereich für die Daten angelegt und alles (inklusive des neuen Eintrags) dort hinüberkopiert. Da so was relativ zeitaufwändig ist, besonders weil es innerhalb einer Schleife durchaus mehrmals geschehen kann, ist es immer gut, nach Möglichkeit vor so einer Operation mittels resize() den Vector mit einer ausreichend großen Kapazität zu versehen.

Oooooops, ich sehe gerade, dass ich resize() und reserve() verwechselt habe! Sorry! Alles, was ich oben gesagt habe, bitte mit *reserve()* , nicht mit resize()  :-(


----------

