Neue Zeile nach x Anzahl an Zeichen



  • Hallo Leute,

    wie könnte man in einen std::string am cleversten einen Zeilenumbruch nach einer bestimmenten Anzahl von Zeichen einfügen. Der Zeilenumbruch sollte allerdings immer nach einem ganzen Wort folgen.
    Hintergrund ist, dass ich in einer Textbox nur eine Breite von 100 Zeichen habe.



  • Fahrrad schrieb:

    wie könnte man in einen std::string am cleversten einen Zeilenumbruch nach einer bestimmenten Anzahl von Zeichen einfügen. Der Zeilenumbruch sollte allerdings immer nach einem ganzen Wort folgen.

    In dem man durch den String durchiteriert und einen Zeiger/Index auf den letzten Zeilenumbruch und das letzte Wortende merkt. Wenn Anzah Zeichen seit letztem Zeilenumbruch >x, dann nimmt man die Zeile zwischen den beiden gemerkten Stellungen.

    Fahrrad schrieb:

    Hintergrund ist, dass ich in einer Textbox nur eine Breite von 100 Zeichen habe.

    In den meisten Toolkits gibts dafür gesonderte Einstellungen, welche GUI verwendest du?


  • Mod

    wie könnte man in einen std::string am cleversten einen Zeilenumbruch nach einer bestimmenten Anzahl von Zeichen einfügen. Der Zeilenumbruch sollte allerdings immer nach einem ganzen Wort folgen.

    So ähnlich?

    #include <iterator>
    #include <locale>
    
    template< typename ForwardIt,
              typename CharT >
    ForwardIt insert_after_word( ForwardIt first,
                                 ForwardIt last,
                                 typename std::iterator_traits<ForwardIt>::difference_type max_distance,
                                 CharT delim,
                                 std::locale const& loc = std::locale{} )
    {
    	if( first == last ) return first;
    
    	ForwardIt last_word_end = first;
    	bool parsing_chars = true;
    
    	while( first != last && max_distance--  )
    	{
    		bool is_space = std::isspace(*first, loc);
    
    		if( parsing_chars && is_space )
    		{
    			parsing_chars = false;
    			last_word_end = first;
    		}
    		else if( !parsing_chars && !is_space )
    			parsing_chars = true;
    
    		++first;
    	}
    
    	*last_word_end = delim;
    	return last_word_end;
    }
    
    #include <iostream>
    
    int main()
    {
    	std::string str = "Hello World, how're you doing? Well, guess what came up in the forum today...";
    
    	auto iter = std::begin(str);
    	do
    	{
    		iter = insert_after_word( iter, std::end(str), 20, '\n' );
    	} while( std::end(str) - iter > 20 );
    
    	std::cout << str;
    }
    


  • Also irgendwie finde ich den Code sehr kompliziert, ich muss ihn mal genauer anschauen.



  • habe jetzt eine eigene Lösung gebaut:

    std::string lineBreak( const std::string& text, const int maxL )
    {
        std::vector<std::string> strs;
        boost::split(strs, text, boost::is_any_of("\t "));
        std::stringstream ss;
        int pos = 0;
        std::vector<std::string>::const_iterator  it = strs.begin();
        std::vector<std::string>::const_iterator end = strs.end();
        while( it != end )
        {
            if( pos + it->size() <= maxL || it->size() > maxL  )
            {
                ss << *it << " ";
                pos += it->size() + 1;
                ++it;
    
            }
            else
            {
                ss << std::endl;
                pos = 0;
            }
    
        }
        return ss.str();
    }
    

    Gibt es daran etwas zu bemängeln?



  • Du solltest aus der while-Schleife eine for-Schleife machen.
    Deine Lösung ersetzt Tabs durch Leerzeichen, das ist bestimmt nicht gewollt.
    Ich würde den stringstream durch einen string ersetzen.
    endl sieht hier wieder sehr seltsam aus. Ich bin dafür endl komplett aus dem Standard zu verbannen. Benutze ein '\n'.


Log in to reply