JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=9729e6fee045f6ab821eb97546ed8f21Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

std::stream Trennzeichen setzen

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
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

BeitragVerfasst am: 03.02.2008, 21:34    Titel: std::stream Trennzeichen setzen Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 03.02.2008, 22:02    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 04.02.2008, 18:10    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 04.02.2008, 20:38    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jonathan_Klein
Living Legend


Alter: 37
Anmeldedatum: 17.02.2003
Beiträge: 3433
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 04.02.2008, 20:46    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 04.02.2008, 22:07    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
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

Impressum