String bis Zeilenende per Stream einlesen
-
Hoi,
ich habe ein Format der Art
<Zahl> <Zahl> <Zahl> [Optionaler String] *Zeilenende*
Zwischen der letzten Zahl und dem String sind beliebig viele Leerzeichen/Tabulatoren.
Meine Lösung ist getline() und den String trimmen.Geht das eleganter, also ohne das trimmen?
Danke und Grüße,
EthonEdit: Ich weiß, ich könnte mit einer manuellen Schleifen Spacces überspringen und dann getline aufrufen. Da es hierbei aber um das Raushängen des C++-Penis geht suche ich die eleganteste Streamlösung.

-
Einfach int lesen, int lesen, int lesen,
Whitespace skippen (Manipulator std::ws),
prüfen ob das nächste Zeichen '\n' ist, wenn ja fertig, wenn nein string lesen.
-
Nur dass '\n' als Whitespace gilt und auch gefiltert wird.
Dh. ich muss die locale ändern.
-
Edit³: Ok, habs. Das ist das Problem...
s
-
C++ und Penis in einem Satz! Der Erfinden von C++ würde sich im Grab umdrehen, wenn er sowas lesen würde.
-
Ethon schrieb:
Nur dass '\n' als Whitespace gilt und auch gefiltert wird.
Dh. ich muss die locale ändern.Oh, stimmt ja.
Mein Fheler.
-
clang schrieb:
C++ und Penis in einem Satz! Der Erfinden von C++ würde sich im Grab umdrehen, wenn er sowas lesen würde.
Zum Glück lebt er noch ...
-
Hi Ethon,
wenn es hier um 'ne C++-raushängende Lösung geht, wie wäre es dann mit einer gettrimmedline-Funktion - als Pendant zu std::getline:
#include <iostream> #include <string> #include <locale> // std::ctype #include <sstream> // std::istringstream (s.main) template< typename E, typename Traits > std::basic_istream< E, Traits >& gettrimmedline( std::basic_istream< E, Traits >& in, std::basic_string< E, Traits >& str ) { std::basic_istream< E, Traits >::sentry ok( in, true ); // true := noskipws if( ok ) { std::ios_base::iostate state = std::ios_base::goodbit; try { bool readsome = false; std::basic_string< E, Traits >::size_type len = 0; str.clear(); const std::ctype< E >& ctype_ = std::use_facet< std::ctype< E > >( in.getloc() ); const E delim = ctype_.widen('\n'); for(;;) { const Traits::int_type m = in.rdbuf()->sbumpc(); if( Traits::eq_int_type( m, Traits::eof() ) ) { state |= std::ios_base::eofbit; break; } const E c = Traits::to_char_type( m ); readsome = true; if( Traits::eq( c, delim ) ) // Zeilenende break; if( ctype_.is( std::ctype_base::space, c ) ) { if( str.empty() ) continue; // überliest führende white character } else len = str.length()+1; // Länge merken mit dem letzten 'not white character' str.append( 1, c ); } if( readsome ) str.resize( len ); // ggf. white character am Ende entfernen else state |= std::ios_base::failbit; } catch( ... ) { state |= std::ios_base::badbit; if( in.exceptions() & std::ios_base::badbit ) throw; } in.setstate( state ); } return in; } int main() { using namespace std; istringstream in( "1 23 45 das ist ein Text \n" "1 67 89\n" "1 -9 23 \n" "1 17 89" // Bem.: 'Leerer' Inhalt führt zu Fehler ); int a, b, c; for( string s; gettrimmedline( in >> a >> b >> c, s ); ) cout << "Optionaler Text: [" << s << "]" << endl; return 0; }Gruß
Werner