String wiedergeben



  • RussianTux schrieb:

    Ok ich verstehe, pro Klasse werden also genau 1 mal alle Funktionen in den statischen Speicher geschrieben und jedes darauf basierende Objekt, wendet sich dann an diesen statischen Speicher um eine Methode aufzurufen, richtig?

    Ja, mehr oder weniger. Aber nicht pro Klasse oder pro sonst was. Methoden und freie Funktionen sind hier gleich. Wann wie und wo Code in den Speicher geladen wird kannst du so nicht beeinflussen.

    RussianTux schrieb:

    wenn das so ist, ist dieser Aufwand also gar nicht erst nötig und die Klasse kann ganz einfach geschrieben werden:

    Noch besser: Der Aufwand ist gar nicht erst nötig und man könnte einfach std::string nutzen.

    Ich kann wirklich verstehen, wenn man nicht von externen Bibliotheken abhängen will. Ja, wirklich, ich kann das schon fast zu gut verstehen. Aber die Standardbibliothek nicht nutzen? 😮 Da sollte man schon sehr gute Gründe haben.



  • cooky451 schrieb:

    RussianTux schrieb:

    Ok ich verstehe, pro Klasse werden also genau 1 mal alle Funktionen in den statischen Speicher geschrieben und jedes darauf basierende Objekt, wendet sich dann an diesen statischen Speicher um eine Methode aufzurufen, richtig?

    Ja, mehr oder weniger. Aber nicht pro Klasse oder pro sonst was. Methoden und freie Funktionen sind hier gleich. Wann wie und wo Code in den Speicher geladen wird kannst du so nicht beeinflussen.

    RussianTux schrieb:

    wenn das so ist, ist dieser Aufwand also gar nicht erst nötig und die Klasse kann ganz einfach geschrieben werden:

    Noch besser: Der Aufwand ist gar nicht erst nötig und man könnte einfach std::string nutzen.

    Ich kann wirklich verstehen, wenn man nicht von externen Bibliotheken abhängen will. Ja, wirklich, ich kann das schon fast zu gut verstehen. Aber die Standardbibliothek nicht nutzen? 😮 Da sollte man schon sehr gute Gründe haben.

    Ich hab eigene Methoden zur Bearbeitung von Textzeilen, jetzt brauche ich nur einen Puffer für den Text, Opeartorenüberladung inerhalb der Klasse und Methoden die auf Funktionen verweisen...

    Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür



  • RussianTux schrieb:

    Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür

    Gut gewarteter, relativ effizienter Code der extrem gut getestet ist und unglaublich gutes Wiederverwendungspotenzial hat? Na, du hast recht, gibt keinen Grund.

    //edit wieviele Zeilen hat eigentlich deine Splitfunktion? Also meine hat 10.



  • RussianTux schrieb:

    Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür

    Vorteile:
    - Die Klasse hat sehr sicher keine Speicherlecks oder sonstige Scherze.
    - Die Klasse ist sehr sicher performanter als Deine.
    - Die Klasse ist bekannt und weitläufig genutzt, deine Algorithmen integrieren sich also besser in bestehende Projekte.

    Nachteile: 😕



  • otze schrieb:

    RussianTux schrieb:

    Wozu brauche ich die std::string lib? Ich sehe keinen einzigen Grund dafür

    Gut gewarteter, relativ effizienter Code der extrem gut getestet ist und unglaublich gutes Wiederverwendungspotenzial hat? Na, du hast recht, gibt keinen Grund.

    //edit wieviele Zeilen hat eigentlich deine Splitfunktion? Also meine hat 10.

    1. Meine Funktionen sind ebenfalls getestet und brauchen nur ein Klassen-Overlay 😃 das wars, WOZU std::string блеать ?! 😕

    2. Meine Splitfunktion ist auf reiner C/C++ Syntax geschrieben und funktioniert ohne jegliche Bibliotheken, 99% frei von allem...



  • 🙄



  • Beantworte mal meine Frage. std::string hat viele Vorteile und keine Nachteile. Erinnert mich an bisschen an die GoingNative Frage an Sutter, da hat auch jemand erzählt, wie seine Arbeitskollegen die Standardbibliothek als irgendetwas externes sehen und sie nicht benutzen wollen. (Gab viel Gelächter danach.) Also los, bau dir eine eigene Stringklasse, aber finde dich damit ab das Gespött der std::string-Kenner zu sein. (Und das sind viele.)



  • RussianTux schrieb:

    1. Meine Funktionen sind ebenfalls getestet und brauchen nur ein Klassen-Overlay 😃

    Mal ganz davon abgesehen, dass ich nicht sehe, wieso man noch Memberfunktionen braucht, wenn es das Ganze schon als freie Funktionen gibt, kannst du bitte mal zwei, drei Algorithmen posten?



  • Michael E. schrieb:

    RussianTux schrieb:

    1. Meine Funktionen sind ebenfalls getestet und brauchen nur ein Klassen-Overlay 😃

    Mal ganz davon abgesehen, dass ich nicht sehe, wieso man noch Memberfunktionen braucht, wenn es das Ganze schon als freie Funktionen gibt, kannst du bitte mal zwei, drei Algorithmen posten?

    Ohne Klassen-Overlay:

    const char* string1 = "text1", string2 = "TEXT2";
    
    //eine der einfachsten algorithmen...
    string1 = s_convert_toUpper(string1);
    string2 = s_convert_toLower(string2);
    
    cout << string1 << "\n";
    cout << string2 << "\n";
    

    Mit Klassen-Overlay

    String string1 = "text1", string2 = "text2";
    
    string1.convert_toUpper();
    string2.convert_toLower();
    
    cout << string1 << "\n";
    cout << string2 << "\n";
    

    Beides funktioniert, aber das 2te ist etwas geordneter



  • Geschmackssache. Aber kannst du bitte noch zwei nicht triviale Algorithmen posten? Danke.



  • Das ist ja noch schlimmer als bei std::string, und da sind die Memberfunktionen schon nicht mehr das Wahre.

    @TE Google mal nach "prefer non-member non-friend functions". Da gibt es zwar noch Spielräume (meiner Meinung nach), aber solche Dinge sollten definitiv freie Funktionen sein.



  • Der Vorteil kehrt sich um, sobald du den String selbst nicht verändern willst und das Resultat daher in einem anderen Ziel speichern musst.

    Wie sieht denn dein convert_toUpper aus? Meins funktioniert ungefähr so:

    void convert_toUpper(std::string& str){
        std::transform(str.begin(),str.end(),str.begin(),std::toupper);
    }
    

    //edit oder für wide character unterstützung:

    template<class CharT, class Alloc>
    void convert_toUpper(std::basic_string<CharT,Alloc>& str){
        typedef std::basic_string<CharT,Alloc> String;
        String::iterator end = str.end();
        std::locale loc;
        for(String::iterator pos = str.begin(); pos != end; ++pos){
            *pos=std::toupper(*pos,loc);
        }
    }
    


  • Michael E. schrieb:

    Geschmackssache. Aber kannst du bitte noch zwei nicht triviale Algorithmen posten? Danke.

    Ausnahme mäßig ja, zwei vergleichsweise kleinen Algorithmen s_convert_toUpper & s_get_lenght:

    const char* s_convert_toUpper(const char* string)
    	{
    		if(string[0] == '\0')
    			return "";
    		const char* buffer_out;
    		unsigned int buffer_size = S_BUFFER_STARTSIZE;
    		char* buffer = new char[buffer_size];
    		unsigned int pos_str;
    		for(pos_str = 0; string[pos_str] != '\0'; pos_str++)
    		{
    			if(pos_str > buffer_size)
    			{
    				buffer_size *= 2;
    				char* buffer_sec = buffer;
    				buffer = new char[buffer_size];
    				unsigned int pos_b = 0, pos_bs = 0;
    				for(pos_b = 0, pos_bs = 0; buffer_sec[pos_bs] != '\0'; pos_b++, pos_bs++)
    				{
    					buffer[pos_b] = buffer_sec[pos_bs];
    				}
    				buffer[pos_b] = '\0';
    			}
    			//if character is a small one
    			if(string[pos_str] <= 122 && string[pos_str] >= 97)
    				buffer[pos_str] = (string[pos_str] - 32);
    			else
    				buffer[pos_str] = string[pos_str];
    		}
    		buffer[pos_str] = '\0';
    		buffer_out = buffer;
    		return buffer_out;
    	}
    
    unsigned int s_get_lenght(const char* string)
    	{
    		unsigned int count;
    		for(count = 0; string[count] != '\0'; count++);
    		return count;
    	}
    

    Nahezu alle Algorithmen funktionieren durch Iteration, man geht Stück für Stück durch die Zeile...

    Mehr werde ich leider nicht veröffentlichen dürfen...



  • WTF machst du da?

    void to_lower(std::string& s)
    {
      std::transform(s.begin(), s.end(), s.begin(), std::tolower);
    }
    


  • Das habe ich mir schon fast gedacht. Soviel zum Thema "getestet".

    const char* s_convert_toUpper(const char* string)
    	{
    		if(string[0] == '\0')
    			return "";
    

    Hier gibst du einen Pointer auf "" zurück, im Normalfall aber mit new angelegten Speicher. Soll der Aufrufer nun den Rückgabewert deleten oder nicht?

    const char* buffer_out;
    		unsigned int buffer_size = S_BUFFER_STARTSIZE;
    		char* buffer = new char[buffer_size];
    		unsigned int pos_str;
    		for(pos_str = 0; string[pos_str] != '\0'; pos_str++)
    		{
    			if(pos_str > buffer_size)
    

    Falsche Bedingung. Bereits für pos_str == buffer_size musst du das Array vergrößern.

    {
    				buffer_size *= 2;
    				char* buffer_sec = buffer;
    				buffer = new char[buffer_size];
    				unsigned int pos_b = 0, pos_bs = 0;
    				for(pos_b = 0, pos_bs = 0; buffer_sec[pos_bs] != '\0'; pos_b++, pos_bs++)
    				{
    					buffer[pos_b] = buffer_sec[pos_bs];
    				}
    

    Da du buffer_sec nicht nullterminiert hast, funktioniert dieses Kopieren (warum benutzt du eigentlich nicht eine Kopiermethode aus der Standardbibliothek wie memcpy?) nicht. Außerdem deletest du das alte Array nicht, sodass du ein Speicherleck hast.

    Immer noch sicher, dass du nicht std::string benutzen möchtest, wo die Funktion ein Einzeiler ist?



  • RussianTux schrieb:

    Nahezu alle Algorithmen funktionieren durch Iteration, man geht Stück für Stück durch die Zeile...

    Und was genau ist an dem Scheiß jetzt besser als richtiges C++?

    RussianTux schrieb:

    Mehr werde ich leider nicht veröffentlichen dürfen...

    Finde ich auch.

    Michael E. schrieb:

    Das habe ich mir schon fast gedacht. Soviel zum Thema "getestet".

    const char* s_convert_toUpper(const char* string)
    	{
    		if(string[0] == '\0')
    			return "";
    

    Hier gibst du einen Pointer auf "" zurück, im Normalfall aber mit new angelegten Speicher. Soll der Aufrufer nun den Rückgabewert deleten oder nicht?

    Die naheliegende Lösung: Nie irgendwas freigeben 👍
    Ist sogar total effizient, man spart ja die ganzen free -Aufrufe.
    Alle modernen Sprachen haben einen GC, also sollte das kein Problem sein.



  • Man könnte jetzt noch hinzufügen, dass der Code implizit auch noch annimmt, dass das System einen ASCII-konformen Zeichensatz verwendet der auf gar keinen Fall internationalisierte Zeichen wie ä,ö, und ü enthält. Ich kenne aus dem Stehgreif Systeme, bei denen der Code nicht zufriedenstellend funktioniert - zum Beispiel an dem wo ich gerade sitze. Aber ich kenne kein System, wo es nicht zumindest die c-Version von toupper gibt.



  • TyRoXx schrieb:

    Und was genau ist an dem Scheiß jetzt besser als richtiges C++?

    👍 Zum Glück ist volkard momentan irgendwie abwesend, der wäre glatt vom Balkon gesprungen hätte er den Code lesen müssen.



  • Nur um das nochmal klarzustellen: Meine Bitte nach Code war nicht, um sich über dich lustig zu machen. Mir war ziemlich klar, dass dein Code ungefähr so aussehen würde und dass du dir der Probleme nicht bewusst bist. Manchmal muss man aber glaube ich die Leute etwas auflaufen lassen, damit sie sich von besseren Lösungen überzeugen lassen 😉



  • Man muss aber dazu sagen, dass es natürlich auch mit c-strings viel schöner ginge:

    const char* toUpper(const char* str){
        std::size_t size = std::strlen(str);
        const char* result = new char[size];
        std::transform(str,str+size,result,std::toupper);
        return result;
    }
    

    Der Aufrufer muss sich natürlich immer noch mit dem delete rum plagen, das würde einem erst der string abnehmen:

    std::string toUpper(std::string const& str){
        std::string result(str.size());
        std::transform(str.begin(),str.end(),result.begin(),std::toupper);
        return result;
    }
    

    Aber wie du siehst wird der Code dadurch schon viel übersichtlicher und eine Menge der ätzenden Fehlerquellen werden einem abgenommen.


Anmelden zum Antworten