W
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