PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Aus stringstream einen ganzen string extrahieren!


liquid
2003-08-29, 17:46:07
Also, umes kurz zu machen.

Ich hab hier einen stringstream (std::stringstream um genau zu sein) den ich in einem Teil des Programms mit Daten fülle. Das sind ganz verschiedene Sachen unter anderem sind noch Zeilensprünge dabei ('\n' und das berühmte std::endl).

Jetzt wird der strstream an eine Instanz übergeben, die diesen wieder aufdröseln soll. Das soll so geschehen, dass der strstream in mehrere strings zerlegt wird, wobei die einzelnen strings die Zeilen im stream darstellen (hoffe ihr versteht das, wie ich das hier meine).
Jedenfalls soll, wenn ich einen Zeilenumbrauch drin habe nachher zwei strings rauskommen, wenn ich mehrere habe halt die Anzahl der vorhandenen Zeilen im stream.

Wie lässt sich das am einfachsten (und möglichst mittels der C++ Mittel (also bitte nicht C-style)) bewerkstelligen?

Danke schonmal!!

cya
liquid

Tom Servo
2003-08-29, 20:10:59
Es gibt für stringstream eine getline() Member-Funktion: http://www.cplusplus.com/ref/iostream/stringstream/
http://www.cplusplus.com/ref/iostream/istream/getline.html

Die wird von istream geerbt. Wirklich sehr übersichtlich dargestellt auf der Webseite.

Die arbeitet zwar mit char[], aber man könnte es natürlich leicht in einer Funktion kapseln, die dann einen string zurückgibt. Man kann auch eine Klasse line schreiben, welche dann den >> Operator überlädt. Ist ja eigentlich C++ Style, dass man zwar noch char * benutzt, aber die Sache dann nach aussen hin hübsch verpackt.

Falls du doch das alte strstream (du schreibst oben mal das eine mal das andere) meinst, gibts dort viellleicht auch gets() anstelle getline(). Bin mir da jetzt auch nicht mehr sicher.

liquid
2003-08-29, 22:00:57
Jo, ich meinte den neuren stringstream. Habe strstream nur als Abkürzung geschrieben.
Den Link kannste ich schon, ich hatte eher an eine andere Möglichkeit gedacht, weil bei der dort beschriebenen Methode ein großes Problem auftritt.

Und zwar wird kein char-pointer zurückgegeben, sondern ich selber muss getline() ja ein Pointer auf ein char-array übergeben. Und das muss wiederum groß genügend dimensioniert sein. Da bleibt wohl als einzige Möglichkeit ein entsprechend großes statisches array zu erstellen und dann alles darüber laufen zu lassen. Und das wollte ich eigentlich bei der ganzen Sache vermeiden.

Vielleicht hat jemand noch eine andere Möglichkeit, jedenfalls schreib ich jetzt mal was ich mir so vorgestellt habe.

Also...
Was ich brauche sind eigentlich nur die Positionen der Zeilenumbrüche, damit kann ich den String in der besagten Funktion sehr leicht zerlegen.

Mal angenommen die Positionen sind mithilfe von Iteratoren dargestellt.

Ich finde die Positionen dadurch indem ich aus dem stream der string extrahieren (mit str()) und dann mit einem Iterator drübergehe und den Iterator in einem skalierbaren Datentyp (zb. vector) speichere, wenn ich auf einen Zeilenumbruch treffe.

Diese Iteratorliste kann dann zum Zerlegen des strings verwendet werden.
Was meint ihr dazu? Wär das ne gute Möglichkeit oder würdet ihr einfach nen char array[4096] anlegen und gut ist?

@alle, die gleich sagen ich mache mir zuviele Sorgen (wegen Performance *g*): es soll halt möglichst elegant und nicht mit brute-force Methoden gearbeitet werden! :D

cya
liquid

liquid
2003-08-30, 01:42:34
Nachtarbeiter meldet sich noch einmal zu Wort bevor ich erschöpft ins Bett falle.

Habe das Problem gelöst. Und zwar mit der "Iterator-Methode". Ich habe nur keine Iteratoren genommen sondern Integer-Datentypen vom Typ std::string::size_type (KA wie genau die definiert sind, bestimmt longs oder ulongs).

Ein vector nimmt diese size_types auf und speichert sie. Im anderen Programmteil kann ich dann mit diesen Positionsangaben den String wieder leicht zerlegen.

Aber da drängt sich schon eine weitere Frage auf (die hat auch mit dem Thema zu tun, deshalb mache ich auch erstmal keinen neuen Thread auf).

Ich habe ja meine Vektor-Klasse. Ich möchte jetzt entsprechend die Operatoren << und >> überladen, damit ich folgendes machen kann.

std::cout << vektor_instanz;

(vektor_instanz >> std::cout) <- geht sowas überhaupt auch?? (hab das noch nie ausprobiert)

Mir geht es eigentlich darum, dass ich den Vektor leicht in einen solchen stringstream "schleusen" kann, damit er bequem weiterverarbeitet werden kann.

Wie lautet dabei der korrekte Syntax für eine solche Überladung? Muss ich das ganze extern deklarieren und friend setzen oder kann ich das direkt in der Klasse machen?

Und was genau gebe ich am besten zurück? Also was für ein stream? Einen stringstream? Ich meine schonmal gesehen zu haben, dass istreams verwendet werden. Was ist daran anders, besser oder wie sollte man es generell (gibts dafür besondere Regelungen) aufziehen?

cya
liquid

liquid
2003-08-30, 11:49:03
Hab das Problem auch allein lösen können. Ist ja eigentlich auch ganz einfach. Kurz ein wenig Code...

Die basic_vector.h:
class basic_vector
{
public:
...
friend std :: ostream& operator<< (std :: ostream& os, const basic_vector& vec);
...
};

std :: ostream& operator<< (std :: ostream& os, const basic_vector& vec);

Die basic_vector.cpp:
...
std :: ostream& operator<< (std :: ostream& os, const basic_vector& vec)
{
os << "v(" << vec.xyz[0] << '|' << vec.xyz[1] << '|' << vec.xyz[2] << ")\n";
return os;
}

Funzt wunderbar und macht die Ausgabe von Vektoren auf die Konsole erheblich einfacher.

cya
liquid

EDIT: Das Forum meint bei solchen Beiträgen mit Code-Abschnitten, dass ich zuviele Smilies benutzen würde. Sind bestimmt die vielen ::, die das Forum verwirren. Warum wird dieser Check allerdings in Code-Blöcken durchgeführt, das ist doch unsinnig.