Teile eines Strings zurückgeben



  • Ich bin grad dabei eine Art Textarea Control zu schreiben. Dazu hab ich mir eine Miniklasse geschrieben die Strings zeilenweise zurückgibt. Jetzt wollte ich aber nicht immer eine Kopie eines Auschnittes aus einem String zurückgeben, da das Kopieren sicher recht lange dauert. Deshalb geb ich einen Iterator auf den Anfang und auf das Ende zurück

    main.cpp

    #include <iostream>
    #include "../libs/stringlinewrapper.hpp"
    
    int main(void)
    {
        StringLineWrapper str(10);
        std::string::iterator striter;
        STRINGITERATORS striters;
        str.GetString().append("Das ist ein Satz der laenger als 10 Zeichen ist.");
        for (uint i = 0; i < str.GetLines(); ++i)
        {
            striters = str.GetLine(i);
            for (striter = striters.begin; striter < striters.end; ++striter)
            {
                std::cout << *striter;
            }
            std::cout << std::endl;
        }
    }
    

    stringlinewrapper.cpp

    #include "stringlinewrapper.hpp"
    
    StringLineWrapper::StringLineWrapper(uint LineLength) : LineLength(LineLength) {}
    
    STRINGITERATORS StringLineWrapper::GetLine(uint Line)
    {
        if (Line >= this->GetLines())
        {
            throw std::out_of_range("StringLineWrapper::GetLine() not in range");
        }
    
        STRINGITERATORS StrIterators;
        StrIterators.begin = this->String.begin() + Line * this->LineLength;
        if (Line == this->GetLines() - 1)
        {
            StrIterators.end = this->String.end();
        }
        else
        {
            StrIterators.end = StrIterators.begin + this->LineLength;
        }
        return StrIterators;
    }
    
    uint StringLineWrapper::GetLines(void)
    {
        return this->String.length() / this->LineLength + 1;
    }
    
    std::string &StringLineWrapper::GetString(void)
    {
        return String;
    }
    

    stringlinewrapper.hpp

    #include <stdexcept>
    #include "CustomTypenames.h"
    
    typedef struct _StringIterators {
        std::string::iterator begin;
        std::string::iterator end;
    } STRINGITERATORS, *LPSTRINGITERATORS;
    
    class StringLineWrapper
    {
    private:
    
        std::string String;
        uint LineLength;
    
    public:
    
        StringLineWrapper(uint LineLength);
        STRINGITERATORS GetLine(uint Line);
        uint GetLines(void);
        std::string &GetString(void);
    };
    

    (Den Code hab ich jetzt nur in ein paar Minuten hingeschrieben. Nur um das Prinzip zu zeigen.)

    Nun wollte ich fragen, ob das eine sinnvolle Möglichkeit ist dieses Problem zu lösen und ob es vielleicht noch bessere bzw. schnellere Möglichkeiten gibt, da es in meinem Programm ziemlich auf die Performance ankommt.



  • Also wenn du wirklich auf die Performance gehen willst, dann würde ich das eher mit den C-Strings machen, als std::string. Da kommen halt so Sachen, wie Boundchecks noch rein, aber die kannst du ja optional machen ( Makros ) so, dass der Benutzer selbst entscheiden kann, ob er sich selbst um die Gültigkeit kümmern will oder nicht.

    Ansonsten gibt es hier:
    http://www.cplusplus.com/reference/string/string/substr.html

    string Funktionalität, die tendenziell wahrscheinlich schneller ist, als etwas selbstgebasteltes.



  • boost::range ist hier wohl genau das was du suchst.

    Im Prinzip eignet sich natuerlich hier auch eine eigene string klasse die nicht kopiert sondern nur zeiger in den string hinein besitzt.



  • Danke für die Antworten. Ich werde mir dann wohl meine eigene kleine Stringklasse schreiben.



  • Caster schrieb:

    Danke für die Antworten. Ich werde mir dann wohl meine eigene kleine Stringklasse schreiben.

    👍


Anmelden zum Antworten