string-klasse



  • Original erstellt von Dimah:
    Shade Of Mine du vergisst das er ein eigenes os macht, klar wäre ein tolower besser aber soll er die komplete cstdlib nach programmieren?

    jein.

    ein tolower/toupper braucht er sowieso!
    ein strlen auch.

    sicher muss er nicht die ganze C Library nachprogrammieren - aber die wichtigsten sachen...

    oder willst du immer wenn du tolower brauchst eine schleife machen in der du mit ascii code rumspielst?

    gerade wenn man ein OS schreibt - sollte man ordentliche bibliotheksfunktionen bereit stellen - sonst hat man doch keinen spaß daran, programme für das OS zu schreiben...



  • Original erstellt von Dimah:
    Shade Of Mine du vergisst das er ein eigenes os macht, klar wäre ein tolower besser aber soll er die komplete cstdlib nach programmieren?

    ja. nur so lassen sich auch weiterhin vernünftig programme portieren.



  • Danke für die vielen "Verbesserungsvorschläge".
    Also mal ein paar Worte zu meiner Verteidigung:

    Wie ich ja schon sagte bin ich ein Anfänger. Ich wollte einfach mal ein bisschen rumprobieren um ein bisschen Erfahrung im Umgang mit C++ zu bekommen.
    Also habe ich zu Übungszwecken alle Methoden selbst geschrieben. Ich wollte eben meine eigene Klasse ohne includes schreiben.

    So und nun ´ne Frage:

    char* str1 = "String";
    char* str2 = "...";

    Wenn ich nun

    str2 = str1;

    schreibe, was passiert dann? Wird der Wert von str1 str2 zugewiesen oder zeigt hiernach str2 einfach nur auf str1?

    Und noch eine Frage zu Refenzen:
    Also im Buch stand dass ich auf keinen Fall NULL-Referenzen fabrizieren solle.
    Aber das "darf" ich doch, so lange ich diese Referenz nicht mehr verwende ist das doch egal, oder?

    [ Dieser Beitrag wurde am 08.05.2003 um 17:25 Uhr von Pogo editiert. ]



  • Noch was:

    Was macht die Methode tolower, die ich schon in der lib finden kann?
    Gibt es da einen so großen Unterschied zu meiner Version?
    Sicherlich wird diese nicht ganz so stümperhaft wie meine sein, aber sie wird doch im Prinzip das gleiche machen, oder? Und um irgendwelche bestimmten Zeichencodes brauch eich mir ja auch keine Sorgen machen, da ja eigentlich die ersten 256 Zeichen der ganzen Zeichencodes übereinstimmen.

    @ "Shadow of Mine"

    Welche Methoden findest du verwirrend? 🙂



  • Original erstellt von Pogo:
    **@ "Shadow of Mine"

    Welche Methoden findest du verwirrend? :)**

    Shade, bitte 🙂

    zB regionMatches (viel zu lange), concat (irgendwie so viele while schleifen 😕) und replace (soviele ifs).



  • und noch was:

    String::String(char* string) {

    value = string;
    length = getLength(string);
    }

    was, wenn der pointer string nach dem aufruf dieses ctors deleted wird?? dann ist value ungültig! also muss man erst noch speicher reservieren, und zwar length+1 byte und dann strcpy&co benutzen. bei mir sähe das dann so aus:

    String::String(char* string) {
    length = getLength(string);
    value = new char[length+1]
    strcpy (value, string);
    }

    naja, wie gesagt, das einzige problem bei meiner str-klasse ist, das es speicher-lecks gibt und wenn ich das beheben will, stürzt er immer ab...
    eine eig. speicherverwaltung hab ich natürlich auch, genauso wie viele routinen der cstdlib (oft allerdings mit anderem namen, z.b. string_copy usw. (das is gerade für den anfänger noch verständlicher 🙂 (auch wenn ich mich schon eone weile nicht mehr als solchen betrachte...)

    cu todo



  • Ich habe meine Klasse jetzt auch in einigen Bereichen verbessert:

    class String {
    
    public:
        String(char* string); // Konstruktor
        String(String &string); // der parameter senseless ist sinnlos und wird nicht gebraucht, muss aber übergeben werden
        String();
        ~String();
        bool equals(String &string) const;
        bool equals(char* string) const; // String vergleichen, beachtet Groß-Kleinschreibung.
        int getLength() const; // Liefert die Länge des instanzeigenen Strings zurück.
        int getLength(char* string) const; // Liefert Länge des übergebenen Strings zurück.
        char charAt(int index) const; // Liefert char am Index index zurück.
        bool equalsIgnoreCase(String &string) const; // String vergleichen ohne Groß-/Kleinschreibung zu beachten.
        bool equalsIgnoreCase(char* string) const; 
        bool regionMatches(bool ignoreCase, int toffset, String &other, int ooffset, int len) const; // ignoreCase = Groß-/Kleinschreibung beachten
                                                                                              // toffset = index ab wann hiesiger String verglichen werden soll
                                                                                              // other = zu vergleichener String
                                                                                              // ooffset = index ab dem anderer (zu vergleichener) String verglichen werden soll
                                                                                              // len = Länge des String der übereinstimmen soll 
        bool regionMatches(bool ignoreCase, int toffset, char* other, int ooffset, int len) const;  
        bool startsWith(String &string) const; // Prüft ob der Anfang des Strings mit "string" übereinstimmt.
        bool startsWith(char* string) const;
        bool endsWith(String &string) const; // Prüft ob das Ende des Strings mit "string" übereinstimmt.
        bool endsWith(char* string) const;
        void concat(String &string); // Die Verkettung dieses Strings mit string.
        void concat(char* string);
        char* toCharPointer(); // Gibt String-Objekt in einem char-Zeiger(char*) zurück.
        void replace(char oldChar, char newChar); // Sucht alle Zeichen oldChar und ersetzt sie durch newChar.
        void replaceCharAt(int index, char newChar);
        void replace(char* oldString, char* newString); // Sucht alle Strings oldString und ersetzt die komplett durch newString, dürfte recht speicherintensiv sein...
        void replace(String &oldString, String &newString);
        int indexOf(String &string, int fromIndex) const; // Erste Position, ab dem Index "index", des in diesem String vollständig enthaltenen Strings "string".
        int indexOf(char* string, int fromIndex) const;
        int lastIndexOf(String &string, int fromIndex) const; // Letzte Position, ab dem Index "index", des in diesem String vollständig enthaltenen Strings "string".
        int lastIndexOf(char* string, int fromIndex) const;
        String substring(int beginIndex) const; // Neuen String ab Index "index" erstellen.
        String substring(int beginIndex, int endIndex) const; // Neuen String von Index "beginIndex" bis zu Index "endIndex" erstellen(endIndex inkl.). 
        void toLowerCase();
        void toUpperCase();
        int numberOf(char thatChar) const;
    
        void trim(); // Alle Werte am Anfang und am ende des Strings mit dem Wert kleiner oder gleich 32(whitespace-Zeichen) entfernen.
        void trim(char toTrim);
    
        String operator+(String &string);
        void operator+=(String &string);
        String &operator=(String &string);
        String &operator=(char* string);
    private:
        char* value; // Speichert Inhalt.
        int length;
    };
    
    String::String(char* string) {
    
        length = getLength(string);
        value = new char[length+1];
        int i = 0;
        while (i < length) value[i] = string[i++];
        value[i] = '\0';
    }
    
    String::String(String &string) {
    
        length = string.getLength();
        value = new char[length+1];
        int i = 0;
        char* str = string.toCharPointer();
        while (i < length) value[i] = str[i++];
        value[i] = '\0';
    }
    
    String::String() {
    
        length = 0;
        value = new char[1];
        value[0] = '\0';
    }
    
    String::~String() {
    
        delete [] value;
    }
    
    bool String::equals(String &string) const {
    
        return equals(string.toCharPointer());
    }
    
    bool String::equals(char* string) const {
    
        char *p1, *p2;
        p1 = string;
        p2 = value;
        while (p1[0] != '\0' && p2[0] != '\0') {
            if (p1[0] == p2[0]) {
                ++p1;
                ++p2;
            } else {
                return false;
            }
        }
        return true;
    }
    
    int String::getLength() const {
    
        return getLength(value);
    }
    
    int String::getLength(char* string) const {
    
        char *p = string;
        int c = 0;
        while (p[0] != '\0') { ++p; ++c; }
        return c;
    }
    
    bool String::equalsIgnoreCase(String &string) const {
    
        return equalsIgnoreCase(string.toCharPointer());
    }
    
    bool String::equalsIgnoreCase(char* string) const {
    
        char *p1, *p2;
        p1 = string;
        p2 = value;
        while (p1[0] != '\0' && p2[0] != '\0') {
            if (p1[0] == p2[0]) {
                ++p1;
                ++p2;
            } else if (p2[0] <= 90 && p2[0] >= 65) {
                if (p1[0] == p2[0] + 32) {
                    ++p1;
                    ++p2;
                } else {
                    return false;
                }
            } else if (p2[0] >= 97 && p2[0] <= 122) {
                if (p1[0] == p2[0] -32) {
                    ++p1;
                    ++p2;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }
    
    char String::charAt(int index) const {
    
        char *p2;
        p2 = value;
    
        if (getLength() < index) {
            return -1;
        } else {
            return p2[index];
        }
        return -1;
    }
    
    bool String::regionMatches(bool ignoreCase, int toffset, String &other, int ooffset, int len) const {
    
        return regionMatches(ignoreCase, toffset, other.toCharPointer(), ooffset, len);
    }
    
    bool String::regionMatches(bool ignoreCase, int toffset, char* other, int ooffset, int len) const {
    
        if (length < len) {
            return false;
        }
        if (ignoreCase == true) {
            char *p1, *p2;
            p1 = value;
            p2 = other;
            int tlen = 0;
            for (int i = 0; i < toffset; i++) {
                ++p1;
            }
            for (int j = 0; j < ooffset; j++) {
                ++p2;
            }
    
            while (p1[0] != '\0' && p2[0] != '\0' && tlen < len) {
                ++tlen;
                if (p1[0] == p2[0]) {
                    ++p1;
                    ++p2;
                } else if (p2[0] <= 90 && p2[0] >= 65) {
                    if (p1[0] == p2[0] + 32) {
                        ++p1;
                        ++p2;
                    } else {
                        return false;
                    }
                } else if (p2[0] >= 97 && p2[0] <= 122) {
                    if (p1[0] == p2[0] -32) {
                        ++p1;
                        ++p2;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }
    
            return true;
        } else {
    
            char *p1, *p2;
            p1 = value;
            p2 = other;
            for (int i = 0; i < toffset; i++) {
                ++p1;
            }
            for (int j = 0; j < ooffset; j++) {
                ++p2;
            }
            int tlen = 0;
    
            while (p1[0] != '\0' && p2[0] != '\0' && tlen < len) {
                ++tlen;
                if (p1[0] == p2[0]) {
                    ++p1;
                    ++p2;
                } else {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
    
    bool String::startsWith(String &string) const {
    
        return startsWith(string.toCharPointer());
    }
    
    bool String::startsWith(char* string) const {
    
        char *p1, *p2;
        p1 = value;
        p2 = string;
        int c = 0;
        int len = getLength(string);
        if (len > length) {
            return false;
        }
        while (p1[0] != '\0' && c < length) {
            if (p1[0] == p2[0]) {
                ++c;
                ++p1;
                ++p2;
            } else {
                return false;
            }
        }
    
        return true;
    }
    
    bool String::endsWith(String &string) const {
    
        return endsWith(string.toCharPointer());
    }
    
    bool String::endsWith(char* string) const {
    
        int c = 0;
        char *p1, *p2;
        p1 = value;
        p2 = string;
    
        if (getLength(string) > length - getLength(string)) {
            return false;
        }
    
        while (p1[0] != '\0') {
            ++p1;
    
        }
        while (c < length) {
            --p1;
            ++c;
        }
    
        while (p1[0] != '\0' && p2[0] != '\0') {
            if (p1[0] == p2[0]) {
                ++p1;
                ++p2;
            } else {
                return false;
            }
        }
    
        return true;
    }
    
    void String::concat(String &string) {
    
        concat(string.toCharPointer());
    }
    
    void String::concat(char* string) {
    
        int len = length + getLength(string);
        char* buffer = new char[len];
        int c = 0;
        while (c < length) buffer[c] = value[c++]; 
        while (c < len) buffer[c] = string[c++];
        buffer[c] = '\0';
        value = buffer;
        delete [] buffer;
    }
    
    char* String::toCharPointer() {
    
        return value;
    }
    
    void String::replace(char oldChar, char newChar) {
    
        char *p = value;
    
        while (p[0] != '\0') {
            if (p[0] == oldChar) {
                p[0] = newChar;
            }
            ++p;
        }
    }
    
    void String::replaceCharAt(int index, char newChar) {
    
        if (index >= getLength()) {
            return;
        }
        char *p = value;
        p[index] = newChar;
    }
    
    void String::replace(char* oldString, char* newString) {
    
        if (getLength(oldString) == 0) {
            return;
        } else if (getLength(newString) == 0) {
            return;
        }
        for (int i = 0; i < length; i++) {
            if (regionMatches(false, i, oldString, 0, getLength(oldString))) {
                char *p1;
                p1 = value;
                char* buffer = new char[i]; // Alle chars vor i
                int l = length-i-getLength(oldString);
                char* buffer2 = new char[l]; // alle chars ab i und oldString
                if (getLength(buffer) == 0 && l != 0) {
                    int c = i + getLength(oldString);
                    for (int k = 0; k < l; k++) buffer2[k] = p1[c++];
                    buffer2[l] = '\0';
                    value = buffer;
                    p1 = 0;
                    concat(buffer2);
                    break;
                } else if (i != 0 && l == 0) {
                    for (int j = 0; j < i; j++)  buffer[j] = p1[j];
                    buffer[i] = '\0';
                    value = buffer;
                    p1 = 0;
                    concat(newString);
                    break;
                } else if (i == 0 && l == 0) {
                    p1 = 0;
                    value = newString;              
                    break;
                } else {
                    for (int j = 0; j < i; j++)  buffer[j] = p1[j];
                    buffer[i] = '\0';
                    int c = i + getLength(oldString);
                    for (int k = 0; k < l; k++) buffer2[k] = p1[c++];
                    buffer2[l] = '\0';
                    value = buffer;
                    p1 = 0; 
                    concat(newString);
                    concat(buffer2);
                }
                delete [] buffer;
                delete [] buffer2;
            }
        }
        length = getLength(value);
    }
    
    void String::replace(String &oldString, String &newString) {
    
        replace(oldString.toCharPointer(), newString.toCharPointer());
    }
    
    int String::indexOf(char* string, int fromIndex) const {
    
        int c = 0;
        for (int i = 0; i < fromIndex; i++) ++c;
        while (c < length) {
            if (regionMatches(false, c, string, 0, getLength(string))) {
                return c;
            } else {
                ++c;
            }
        }
        return -1;
    }
    
    int String::indexOf(String &string, int fromIndex) const {
    
        return indexOf(string.toCharPointer(), fromIndex);
    }
    
    int String::lastIndexOf(char* string, int fromIndex) const {
    
        int c = 0;
        int index = 0;
        for (int i = 0; i < fromIndex; i++) c++;
        while (c < length) {
            if (regionMatches(false, c, string, 0, getLength(string))) {
                index = c;
                ++c;
            } else {
                ++c;
            }
        }
        return index;
    }
    
    int String::lastIndexOf(String &string, int fromIndex) const {
    
        return lastIndexOf(string.toCharPointer(), fromIndex);
    }
    
    void String::toLowerCase() {
    
        char *p = value;
        while (p[0] != '\0') {
            if (p[0] <= 90 && p[0] >= 65) p[0] += 32;
            ++p;
        }
    }
    
    void String::toUpperCase() {
    
        char *p = value;
        while (p[0] != '\0') {
            if (p[0] >= 97 && p[0] <= 122) p[0] -= 32;
            ++p;
        }
    }
    
    String String::substring(int beginIndex) const {
    
        return substring(beginIndex, length);
    }
    
    String String::substring(int beginIndex, int endIndex) const {
    
        if (endIndex > getLength() || beginIndex > getLength() || beginIndex > endIndex) return String(value);
        char* buffer = new char[(endIndex-beginIndex)+2];
        char *p = value;
        int c = 0;
        for (int i = 0; i < beginIndex; i++) p++;
        while (p[0] != '\0' && c <= endIndex-beginIndex) {
            buffer[c++] = p[0];
            ++p;
        }
        buffer[c] = '\0';
        return String(buffer);
    }
    
    void String::trim() {
    
        char *p = value;
        int c = 0;
        while (p[c] <= 32) ++c;
        char* buffer = new char[getLength()-c];
        int c2 = 0;
        for (int i = 0; i < length; i++) { buffer[i] = p[c++]; ++c2; }
        buffer[c2] = '\0';
        --c;
        while (p[c] <= 32) { --c; --c2; }
        buffer[c2] = '\0';
        value = buffer;
        delete [] buffer;   
    }
    
    void String::trim(char toTrim) {
    
        char *p = value;
        int c = 0;
        while (p[c] == toTrim) ++c;
        char* buffer = new char[getLength()-c];
        int c2 = 0;
        int length = getLength(buffer);
        for (int i = 0; i < length; i++) { buffer[i] = p[c++]; ++c2; }
        buffer[c2] = '\0';
        --c; --c;
        while (p[c] == toTrim) { --c; --c2; }
        --c2;
        buffer[c2] = '\0';
        value = buffer;
        delete [] buffer;
    }
    
    int String::numberOf(char thatChar) const {
    
        char *p = value;
        int number = 0;
    
        while (p[0] != '\0') {
            if (p[0] == thatChar) {
                ++number;
            }
            ++p;
        }
        return number;
    }
    
    String& String::operator=(String &string) {
    
        if (this == &string) return *this;
        delete [] value;
        length = string.getLength();
        int i = 0;
        value = new char[length+1];
        char* str = string.toCharPointer();
        while (i < length) value[i] = str[i++];
        value[i] = '\0';
        return *this;
    }
    
    String& String::operator=(char* string) {
    
        if (&value == &string) return *this;
        delete [] value;
        length = getLength(string);
        int i = 0;
        value = new char[length+1];
        while (i < length) value[i] = string[i++];
        value[i] = '\0';
        return *this;
    }
    
    String String::operator+(String &string) {
    
        String str = *this;
        str.concat(string);
        return str;
    }
    
    void String::operator+=(String &string) {
    
        concat(string);
    }
    

    Trotzdem habe ich aber auch ein Problem mit delete. Wie z.B.
    in folgender Methode:

    void String::trim() {
    
        char *p = value;
        int c = 0;
        while (p[c] <= 32) ++c;
        char* buffer = new char[getLength()-c];
        int c2 = 0;
        for (int i = 0; i < length; i++) { buffer[i] = p[c++]; ++c2; }
        buffer[c2] = '\0';
        --c;
        while (p[c] <= 32) { --c; --c2; }
        buffer[c2] = '\0';
        value = buffer;
        delete [] buffer;   
    }
    

    Dann tritt irgendein Fehler auf und das Programm wird beendet. Ich habe keine Ahnung warum...
    Wo liegt da der Fehler? Wenn ich im Destruktor value genau so delete kriege ich ja auch keine Fehlermeldung.



  • Ok, ich denke ich weis evtl. wo der Fehler liegt. Irgendwie, klappt das Kopieren von einem String durch meinen =-Operator nicht. Ich habe festgestellt das danach value auf den selben Speicherbereich wie buffer zeigt. Also wurde im Prinzip ja nichst kopiert. Also wie kann ich wirklich kopieren?



  • Und jetzt noch was zu denen, die mir bestimmt gleich erzählen wollen, dass ich doch die stdlib verwenden soll. Also, was macht es für einen Sinn, wenn ich meine eigene Stringklasse schreibe, in dieser aber die Methoden der stdlib aufrufe? Da kann ich doch auch einfach direkt die Methoden dieser lib aufrufen und muss nicht noch Rechenzeit verschwenden in dem ich sie über eine andere Methode die eben einen anderen Namen hat aufrufe. Das ist doch pure Speicherverschwendung. Also ich denke entweder alles oder nichts.



  • void String::concat(char* string) {

    int len = length + getLength(string);
    char* buffer = new char[len];
    int c = 0;
    while (c < length) buffer[c] = value[c++];
    int c2 = 0;
    while (c < len) buffer[c++] = string[c2++];
    buffer[c] = '\0';
    setValue(buffer);
    delete [] buffer;
    }

    Also hier ist auch der gleiche Fehler! Also jedesmal wenn ich in meinen Methoden, außer im Destruktor, delete aufrufe tritt ein Fehler auf! Was mache ich falsch...? 😕 😕 😕



  • Hallo Pogo,
    also ich bin mir nicht ganz sicher, aber könnte es irgendwie problematisch sein, dass Du buffer an value zuweisst und anschliessend delete[] buffer aufrufst 😕 ?

    Beide sind ja vom Typ char* und durch die Zuweisung:

    value = buffer;
    

    kopierst Du ja nicht etwa den Inhalt des Speicherbereiches von buffer in einen anderen Speicherbereich auf den value zeigt, sondern erreichst, dass value auf den gleichen Speicherbereich zeigt wie buffer.

    Zumindest war das auf der vorigen Seite noch so.

    delete[] buffer; müsste also eigentlich den Speicher, auf den value zeigt, freigeben 😕 . Ich weiss nicht, ob der Standard das überhaupt zulässt. Gibt aber bestimmt Compiler, die das eben einfach mitmachen und das Ergebnis ist dann beim nächsten Zugriff auf value eine Speicherverletzung.

    Jetzt sehe ich, dass Du eine Funktion setValue verwendest, die Du wohl neu in die Klasse aufgenommen hast. Wie schaut die denn aus?

    Gruss von
    Qweety,
    der sich auch nicht sicher ist, ob er da auf der richtigen Spur ist.



  • Ich weis, das kommt spät, aber hier die Methode:

    Aber das Problem ist mittlerweile schon gelöst, die Klasse wird ohne Fehler kompiliert und funktioniert(e) auch. Nun habe ich mal nach zig Monaten den Code mal wieder ausgekramt und wollte ihn testen, aber da kam nichts gutes raus. Es liegt aber vermutlich an meinem Programm was es testet, denn als ich es damals testete hat alles wunderbar geklappt :D!
    Hier nochmal das ganze in für meine Begriffe eigentlicher Perfektion 😉 :

    #include "String.h"
    
    String::String(char* string) {
    
    	length = getLength(string);
    	value = new char[length+1];
    	int i = 0;
    	while (i < length) value[i] = string[i++];
    	value[i] = '\0';
    }
    
    String::String(unsigned short len) {
    
    	length = len;
    	value = new char[length];
    }
    
    String::String(String &string) {
    
    	length = string.getLength();
    	value = new char[length+1];
    	int i = 0;
    	char* str = string.toCharPointer();
    	while (i < length) value[i] = str[i++];
    	value[i] = '\0';
    }
    
    String::String() {
    
    	length = 0;
    	value = new char[1];
    	value[0] = '\0';
    }
    
    String::~String() {
    
    	delete [] value;
    }
    
    bool String::equals(String &string) const {
    
    	return equals(string.toCharPointer());
    }
    
    bool String::equals(char* string) const {
    
    	char *p1, *p2;
    	p1 = string;
    	p2 = value;
    	while (p1[0] != '\0' && p2[0] != '\0') {
    		if (p1[0] == p2[0]) {
    			++p1;
    			++p2;
    		} else {
    			return false;
    		}
    	}
    	return true;
    }
    
    int String::getLength() const {
    
    	return getLength(value);
    }
    
    int String::getLength(char* string) const {
    
    	char *p = string;
    	register int c = 0;
    	while (p[0] != '\0') { ++p; ++c; }
    	return c;
    }
    
    bool String::equalsIgnoreCase(String &string) const {
    
    	return equalsIgnoreCase(string.toCharPointer());
    }
    
    bool String::equalsIgnoreCase(char* string) const {
    
    	char *p1, *p2;
    	p1 = string;
    	p2 = value;
    	while (p1[0] != '\0' && p2[0] != '\0') {
    		if (p1[0] == p2[0]) {
    			++p1;
    			++p2;
    		} else if (p2[0] <= 90 && p2[0] >= 65) {
    			if (p1[0] == p2[0] + 32) {
    				++p1;
    				++p2;
    			} else {
    				return false;
    			}
    		} else if (p2[0] >= 97 && p2[0] <= 122) {
    			if (p1[0] == p2[0] -32) {
    				++p1;
    				++p2;
    			} else {
    				return false;
    			}
    		} else {
    			return false;
    		}
    	}
    	return true;
    }
    
    char String::charAt(int index) const {
    
    	char *p2;
    	p2 = value;
    
    	if (length < index) {
    		return -1;
    	} else {
    		return p2[index];
    	}
    	return -1;
    }
    
    bool String::regionMatches(bool ignoreCase, int toffset, String &other, int ooffset, int len) const {
    
    	return regionMatches(ignoreCase, toffset, other.toCharPointer(), ooffset, len);
    }
    
    bool String::regionMatches(bool ignoreCase, int toffset, char* other, int ooffset, int len) const {
    
    	if (length-toffset < len) {
    		return false;
    	}
    	if (ignoreCase == true) {
    		char *p1, *p2;
    		p1 = value;
    		p2 = other;
    		int tlen = 0;
    		for (int i = 0; i < toffset; i++) {
    			++p1;
    		}
    		for (int j = 0; j < ooffset; j++) {
    			++p2;
    		}
    
    		while (p1[0] != '\0' && p2[0] != '\0' && tlen < len) {
    			++tlen;
    			if (p1[0] == p2[0]) {
    				++p1;
    				++p2;
    			} else if (p2[0] <= 90 && p2[0] >= 65) {
    				if (p1[0] == p2[0] + 32) {
    					++p1;
    					++p2;
    				} else {
    					return false;
    				}
    			} else if (p2[0] >= 97 && p2[0] <= 122) {
    				if (p1[0] == p2[0] -32) {
    					++p1;
    					++p2;
    				} else {
    					return false;
    				}
    			} else {
    				return false;
    			}
    		}
    
    		return true;
    	} else {
    
    		char *p1, *p2;
    		p1 = value;
    		p2 = other;
    		for (int i = 0; i < toffset; i++) {
    			++p1;
    		}
    		for (int j = 0; j < ooffset; j++) {
    			++p2;
    		}
    		int tlen = 0;
    
    		while (p1[0] != '\0' && p2[0] != '\0' && tlen < len) {
    			++tlen;
    			if (p1[0] == p2[0]) {
    				++p1;
    				++p2;
    			} else {
    				return false;
    			}
    		}
    		return true;
    	}
    	return false;
    }
    
    bool String::startsWith(String &string) const {
    
    	return startsWith(string.toCharPointer());
    }
    
    bool String::startsWith(char* string) const {
    
    	return regionMatches(false, 0, string, 0, getLength(string));
    }
    
    bool String::endsWith(String &string) const {
    
    	return endsWith(string.toCharPointer());
    }
    
    bool String::endsWith(char* string) const {
    
    	for (int i = length; i > 0; i--) {
    		if (regionMatches(false, i, string, 0, getLength(string)) && length - i == getLength(string)) return true;
    	}
    	return false;
    }
    
    void String::concat(String &string) {
    
    	concat(string.toCharPointer());
    }
    
    void String::concat(char* string) {
    
    	int len = length + getLength(string);
    	char* buffer = new char[len+1];
    	int c = 0;
    	while (c < length) buffer[c] = value[c++]; 
    	int c2 = 0;
    	while (c < len) buffer[c++] = string[c2++];
    	buffer[c] = '\0';
    	setValue(buffer);
    	delete [] buffer;
    }
    
    char* String::toCharPointer() {
    
    	return value;
    }
    
    void String::replace(char oldChar, char newChar) {
    
    	char *p = value;
    
    	while (p[0] != '\0') {
    		if (p[0] == oldChar) {
    			p[0] = newChar;
    		}
    		++p;
    	}
    }
    
    void String::replaceCharAt(int index, char newChar) {
    
    	if (index >= length) {
    		return;
    	}
    	char *p = value;
    	p[index] = newChar;
    }
    
    void String::replace(char* oldString, char* newString) {
    
    	if (getLength(oldString) == 0) {
    		return;
    	} else if (getLength(newString) == 0) {
    		return;
    	}
    	for (int i = 0; i < length; i++) {
    		if (regionMatches(false, i, oldString, 0, getLength(oldString))) {
    			char *p1;
    			p1 = value;
    			char* buffer = new char[i+1]; // Alle chars vor i
    			int l = length-i-getLength(oldString);
    			char* buffer2 = new char[l+1]; // alle chars ab i und oldString
    			if (getLength(buffer) == 0 && l != 0) {
    				int c = i + getLength(oldString);
    				for (int k = 0; k < l; k++) buffer2[k] = p1[c++];
    				buffer2[l] = '\0';
    				setValue(buffer);
    				p1 = 0;
    				concat(buffer2);
    			} else if (i != 0 && l == 0) {
    				for (int j = 0; j < i; j++)	buffer[j] = p1[j];
    				buffer[i] = '\0';
    				setValue(buffer);
    				p1 = 0;
    				concat(newString);
    			} else if (i == 0 && l == 0) {
    				p1 = 0;
    				setValue(newString);				
    			} else {
    				for (int j = 0; j < i; j++)	buffer[j] = p1[j];
    				buffer[i] = '\0';
    				int c = i + getLength(oldString);
    				for (int k = 0; k < l; k++) buffer2[k] = p1[c++];
    				buffer2[l] = '\0';
    				setValue(buffer);
    				p1 = 0;	
    				concat(newString);
    				concat(buffer2);
    			}
    			delete [] buffer;
    			delete [] buffer2;
    		}
    	}
    	length = getLength(value);
    }
    
    void String::replace(String &oldString, String &newString) {
    
    	replace(oldString.toCharPointer(), newString.toCharPointer());
    }
    
    int String::indexOf(char* string, int fromIndex) const {
    
    	for (int i = fromIndex; i < length; i++) {
    		if (regionMatches(false, i, string, 0, getLength(string))) return i;
    	}
    	return -1;
    }
    
    int String::indexOf(String &string, int fromIndex) const {
    
    	return indexOf(string.toCharPointer(), fromIndex);
    }
    
    int String::lastIndexOf(char* string, int fromIndex) const {
    
    	for (int i = length; i > fromIndex; i--) {
    		if (regionMatches(false, i, string, 0, getLength(string))) return i;
    	}
    	return -1;
    }
    
    int String::lastIndexOf(String &string, int fromIndex) const {
    
    	return lastIndexOf(string.toCharPointer(), fromIndex);
    }
    
    void String::toLowerCase() {
    
    	char *p = value;
    	while (p[0] != '\0') {
    		if (p[0] <= 90 && p[0] >= 65) p[0] += 32;
    		++p;
    	}
    }
    
    void String::toUpperCase() {
    
    	char *p = value;
    	while (p[0] != '\0') {
    		if (p[0] >= 97 && p[0] <= 122) p[0] -= 32;
    		++p;
    	}
    }
    
    String String::substring(int beginIndex) const {
    
    	return substring(beginIndex, length);
    }
    
    String String::substring(int beginIndex, int endIndex) const {
    
    	if (endIndex > length || beginIndex > length || beginIndex > endIndex) return String(value);
    	String buffer((endIndex-beginIndex)+2);
    	char *p = value;
    	int c = 0;
    	for (int i = 0; i < beginIndex; i++) p++;
    	while (p[0] != '\0' && c <= endIndex-beginIndex) {
    		buffer[c++] = p[0];
    		++p;
    	}
    	buffer[c] = '\0';
    	return buffer;
    }
    
    void String::trim() {
    
    	char *p = value;
    	int c = 0;
    	while (p[c++] <= 32) {}
    	--c;
    	int c2 = 0;
    	char* buffer = new char[length-c+2];
    	int len = length-c;
    	for (int i = 0; i < len; i++) { buffer[i] = p[c++]; ++c2; }
    	--c2;
    	while (buffer[c2--] <= 32) {}
    	c2 += 2;
    	buffer[c2] = '\0';
    	setValue(buffer);
    	delete [] buffer;
    }
    
    int String::numberOf(char thatChar) const {
    
    	char *p = value;
    	int number = 0;
    
    	while (p[0] != '\0') {
    		if (p[0] == thatChar) {
    			++number;
    		}
    		++p;
    	}
    	return number;
    }
    
    int String::numberOf(char* str) const {
    
    	int i = 0;
    	int number = 0;
    	while (i < length) {
    		if (regionMatches(false, i, str, 0, getLength(str))) {
    			++number;
    			i += getLength(str);
    		} else {
    			++i;
    		}
    	}
    	return number;
    }
    
    int String::numberOf(String str) const {
    
    	return numberOf(str.toCharPointer());
    }
    
    String& String::operator=(String &string) {
    
    	if (this == &string) return *this;
    	delete [] value;
    	length = string.getLength();
    	int i = 0;
    	value = new char[length+1];
    	char* str = string.toCharPointer();
    	while (i < length) value[i] = str[i++];
    	value[i] = '\0';
    	return *this;
    }
    
    String& String::operator=(char* string) {
    
    	if (&value == &string) return *this;
    	delete [] value;
    	length = getLength(string);
    	int i = 0;
    	value = new char[length+1];
    	while (i < length) value[i] = string[i++];
    	value[i] = '\0';
    	return *this;
    }
    
    String String::operator+(String &string) {
    
    	String str = *this;
    	str.concat(string);
    	return str;
    }
    
    void String::operator+=(String &string) {
    
    	concat(string);
    }
    
    void String::setValue(char* string) {
    
    	if (&value == &string) return;
    	delete [] value;
    	length = getLength(string);
    	int i = 0;
    	value = new char[length+1];
    	while (i < length) value[i] = string[i++];
    	value[i] = '\0';
    }
    
    char &String::operator[](unsigned short offset) {
    
    	if (offset > length)
    		return value[length-1];
    	else
    		return value[offset];
    }
    
    void String::setValue(String &string) {
    
    	setValue(string.toCharPointer());
    }
    

Anmelden zum Antworten