letzter Schleifendurchgang anders
-
Angenommen, ich habe so eine Schleife:
for (auto zeichen = stimme.begin(); zeichen != stimme.end(); ++zeichen) { out << zeichen << ' '; }
Jetzt will ich im letzten Durchgang das ' ' weglassen. Dazu böte sich ja an, die Schleife bis
zeichen != stimme.end()-1
laufen zu lassen. Aber dann kommt im Debugmode u.U. ein Fehler, weil stimme.end()-1 ungültig ist, wenn stimme.size() == 0.
Was tun?
-
Gib erst das ' ' und dann das Zeichen aus . Und das erste Zeichen behandelst du gesondert.
-
gute IDee
-
SeppJ schrieb:
Und das erste Zeichen behandelst du gesondert.
Was aber bedeutet, dass die For-Schleife erst beim zweiten Zeichen beginnen darf. Somit hat man wieder das gleiche Problem, nur auf der anderen Seite.
Möglich wäre sowas:
auto end = (stimme.empty() ? stimme.end() : stimme.end() - 1);
-
Nexus schrieb:
Möglich wäre sowas:
Was aber bedeutet, dass eine Seite gesondert behandelt werden muss.
Mit sowas hat man wieder das gleiche Problem, nur auf der anderen Seite:
for (auto zeichen = stimme.empty()?stimme.end():stimme.begin()+1; zeichen != stimme.end(); ++zeichen)
Einziger Unterschied: Man erspart sich eine Zeile.
Wenn du jedoch sicher bist, dass der kleiner-Operator greift (z.Bsp. in allen Arrays und Vectors), würde ich den verwenden:
for (auto zeichen = stimme.begin()+1; zeichen < stimme.end(); ++zeichen)
-
andersrum schrieb:
Wenn du jedoch sicher bist, dass der kleiner-Operator greift (z.Bsp. in allen Arrays und Vectors), würde ich den verwenden
Stimmt, guter Vorschlag. Falls
-1
funktioniert (was Random-Access-Iteratoren impliziert), klappt deroperator<
auch.
-
Das Ausgangsproblem hab ich übrigens relativ oft. Und ich beneide jedesmal die PHPler mit ihrem "implode". Wobei man sich das auch ganz gut nachbauen kann:
#include <iostream> #include <sstream> template<typename T, typename U> U& implode( const T& container, const std::string& separator, U& stream ) { if ( container.begin() == container.end() ) return stream; for ( auto i=container.begin(); ; ) { stream << *i; if ( ++i == container.end() ) break; stream << separator; } return stream; } template<typename T> std::string implode( const T& container, const std::string& separator ) { std::stringstream ss; implode( container, separator, ss ); return ss.str(); } int main() { std::vector<float> k; k.push_back( 1.23 ); k.push_back( 2.34 ); k.push_back( 3.45 ); std::cout << implode( k, "-" ) << std::endl; implode( k, "|", std::cout ) << std::endl; } //Ausgabe: //1.23-2.34-3.45 //1.23|2.34|3.45