|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 03.02.2008, 21:34 Titel: std::stream Trennzeichen setzen |
|
|
So, man kann ja streams immer bis zu Leerzeichen auslesen:
CPP: | stream << "1 2 17 23";
stream >> a >> b >> c >> d;
|
So, wie kann ich jetzt das selbe mit, z.B.:
"1;2;17;23"
erreichen?
(Btw.: Ja, ich habe schon gesucht^^) _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 03.02.2008, 22:02 Titel: |
|
|
Im Grunde musst du den nicht selber setzen, da immer soweit gelesen wird bis ein Zeichen nicht zu dem Typ passt. "1;2;3;4;" kannst du z.B. genauso gut einlesen wie "1 2 3 4 ". Das geht dadurch, dass operator>> type-safe ist. Ansonsten kannst du aber auch noch operator>> überladen und std::getline nutzen, da kannst du als 3. parameter einen "delimiter" übergeben, der den Input stoppt: CPP: | std::getline( stream, s, ';' ); | Auch Ersetzen von ';' durch ' ' vorher würde funktionieren.
Gruß DXer |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 04.02.2008, 18:10 Titel: |
|
|
Hm, gefällt mir irgendwie alles nicht so recht.
Schade dass es da keine einfache und schnelle Lösung gibt. (Alles vorher ersetzen, oder mit getline einen Teilstring hohlen den ich dann noch in eine Zahl umwandeln muss, ist doch alles doof.) _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 04.02.2008, 20:38 Titel: |
|
|
ich hab mal eine kleine Funktion geschrieben die das ermöglicht was du sagst und außerdem (ohne die kommentare)klein und schnell ist. Das ist mit streams ziemlich einfach und nebenbei erfordert die Funktion auch alle Kriterien die streams nach dem c++-standard aufweisen müssen (z.B. setzt sie eof falls das nicht klappt, was sonst normalerweise auch passieren sollte: CPP: | // als istr kannst du jeden möglichen stream der mindestens istream erbt übergeben,
// also auch istringstream oder fstream usw.
// man kann das ganze auch auf deine Bedürfnisse herunterschrauben, und
// so ziemlich viel code sparen, aber ich habs mal allgemein und als template
// geschrieben; namen kannst du ja noch ändern
template<typename T> inline bool read( std::istream& istr, T& var, char delim, bool noWS = false )
{
// falls white space nicht überlesen werden soll und nur delim als
// Trennzeichen gilt
if( noWS )
istr >> std::noskipws;
// standard eingabe testen
if( istr >> var )
return true;
// stream wieder gültig machen und eingabe auf delim testen
char c;
istr.clear();
istr.get( c );
// falls ja, nächste eingabe probieren; falls mehrere <delim> hinterein
// nander gehen sollen, könntest du das hier rekursiv machen,
// also return read(istr, var, delim, noWS), das kann der optimizer
// wegoptimieren; für den MSVC++ compiler auf warning level 3 kann
// man hier auch {return istr >> var ? true : false} angeben, da der
// da bei bool-converting stress macht
if( c == delim )
return istr >> var;
// kein gültiges trennzeichen, den stream auf standard setzen
istr.setstate( istr.eofbit );
return false;
}
// kleines verwendungs beispiel
int main()
{
// die eingabe
std::string s = "9;1 3;4;2 3;4;5 xx4;2;1";
std::istringstream is(s);
// die variable, hier ein int (da template geht auch alles andere)
int a;
// eingabe (falls true als 4. parameter übergeben, bricht die funktion
// schon bei der '3' ab, ansonsten bei 'x'
while( read(is, a, ';') )
std::cout << a;
return 0;
} |
Gruß DXer |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 04.02.2008, 20:46 Titel: |
|
|
hm danke. Aber meinste man könnte auch sowas haben?:
CPP: | stream >> delim(";") >> a >> b >> c >> delim(" ") >> d >> e;
|
Das wäre halt nach der Standardmethode um Parameter für Streams zu setzen. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 04.02.2008, 22:07 Titel: |
|
|
direkt geht sowas nicht, da das berücksichtigen von white space intern in der klasse numpunct in <xlocnum> von den read-buffern gemacht wird und dort etwas anders implementiert ist. Man könnte aber durchaus sowas machen, wenn du wert auf das Manipulatoren Pattern legst: CPP: | // die klasse selbst
template<typename T> class mc_delim
{
public:
mc_delim( char aD, T& aVar ) : d( aD ), var( aVar ) {}
friend inline std::istream& operator>> ( std::istream& istr, const mc_delim& mcd )
{
// hier mit der Methode von meinem letzten Post; da eof in der
// Methode gesetzt wird reicht es, nur istr und nicht den rück-
// gabe wert von read zu beachten
read( istr, mcd.var, mcd.d );
return istr;
}
private:
char d;
T& var;
};
// eine Funktion zur vereinfachung (kann man vllt auch asdelim nennen)
template<typename T> inline mc_delim<T> delim( char aD, T& aVar )
{
return mc_delim<T>( aD, aVar );
}
// statt while( read(is, a, ';') ) jetzt
while( istr >> delim(';', a) )
// man könnte das jetzt auch so machen
const char c = ';';
istr >> delim(c, a) >> delim(c, b) >> d >> e >> delim(c, f); |
über einen weiteren trick kann man sogar sowas machen
CPP: | stream >> delim(";") >> a >> b >> c >> delim(" ") >> d >> e; | dafür müsste man delim() einen placeholder zurückgeben lassen; das ist eine Klasse, die den stream speichert und selber operator>> implementiert. Wenn du willst schreibe ich dir so etwas, aber schau erstmal ob du auch damit zurechtkommst.
Gruß DXer |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|