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?


  • Mod

    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 der operator< 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
    

Log in to reply