istream >> Operator Überladen in eigener String Klasse



  • Hallo, in meiner Belegarbeit habe ich zur Aufgabe, eine eigene Stringklasse zu programmieren. Ich komme allerdings bei dem >> Operator nicht ganz zurecht.

    Hier mein Code

    String.cpp

    CString::CString(const char *Str)
    {
        this->length = strlen(Str);
        this->str = new char[length+1];
        strcpy(this->str,Str);
    }
    
    std::istream CString::&operator>> (std::istream &is, CString &pStr)
    {
        this->length = strlen(pStr.str);
        this->str = new char[this->length + 1];
        is >> this->str;
    }
    

    String.h

    //
    #ifndef __Beleg_II__String__
    #define __Beleg_II__String__
    
    #include <iostream>
    #include <cstring>
    
    class CString
    {
    private:
        char *str;
        size_t length;
    
    public:
        CString(const char *Str);
        CString();
        CString(char x, int n);
    
        void setChar(int idx, char x);
        int  getChar(int idx)const;
        void display()const;
    
        ~CString()
        {
            delete[] str;
        }
    
        CString operator+ (const CString &pStr);
        bool operator== (const CString &pStr);
        friend std::istream &operator>> (std::ifstream &is, CString &pStr);
        friend std::ostream &operator<<(std::ostream &os, const CString &pStr);
    
        char* getStr()const;
        void setStr(char *pStr);
    
    };
    
    #endif /* defined(__Beleg_II__String__) */
    

    main.cpp

    CString Name;
    cin >> Name;
    

    Dabei bekomme ich als Fehlermedung: error: no match for 'operator>>' in 'std::cin >> Name'|

    Habe wirklich keine Ahnung woran es liegt. 😕
    Danke 😋



  • hast mal ifstream statt istream geschrieb.



  • Ja, ifstream steht da. Hab falsch abgeschrieben



  • Neben dem was volkard gesagt hat:

    std::istream CString::&operator>> (std::istream &is, CString &pStr)
    

    Das stimmt auch nicht ganz.



  • Deine Implementierung in der String.cpp ist komplett falsch. Das muss eine freie Funktion sein also ohne CString::, das bedeutet das du auch nicht auf Member zugreifen kannst.

    Und wieso nennst du die Klasse CString, lass das C bitte weg.





  • Könntest du mir ein kleines Beispiel schreiben? Versteh das nicht ganz was du mit freier Funktion meinst



  • Harbor schrieb:

    Könntest du mir ein kleines Beispiel schreiben? Versteh das nicht ganz was du mit freier Funktion meinst

    // Header
    class foo
    {
        int i;
    
    public:
        ...
    
        // friend Deklaration
        friend std::istream& operator>>(std::istream &is, foo &f);
    };
    
    // wirkliche Deklaration
    std::istream& operator>>(std::istream &is, foo &f);
    
    // Implementierung
    std::istream& operator>>(std::istream &is, foo &f)
    {
        return is >> f.i;
    }
    

  • Mod

    Harbor schrieb:

    Könntest du mir ein kleines Beispiel schreiben? Versteh das nicht ganz was du mit freier Funktion meinst

    Der Operator kann keine Memberfunktion deiner Klasse sein. Denn sonst müsste das linksseitige Objekt vom Typ deiner Klasse sein, d.h. du müsstest so etwas wie

    my_string >> cin;
    

    schreiben, um die Funktion aufzurufen. Das geht zwar, ist aber vermutlich nicht gewünscht.
    Du kannst aber auch keine Memberfunktionen zu std::istream hinzufügen, da du weder Zugriff auf die Klassendefinition hast und da das sowieso vom Sprachstandard her verboten ist, dass man so etwas macht.

    Also bleibt nur eine freie Funktion, das heißt eine ganz normale Funktion, die kein Member von irgendeiner Klasse ist. Bloß, dass du sie eben operator>> nennst.

    Also:

    std::istream& operator>> (std::istream &is, CString &pStr);
    

    Siehe auch:
    http://www.c-plusplus.net/forum/232010

    Beachte auch die anderen Antworten hier im Thread, die machen dich auf wichtige Fehler aufmerksam.



  • Ich habe gerade ein ähnliches Problem, von daher denke ich es ist besser es hier reinzuschreiben anstatt einen neuen Thread zu eröffnen.

    friend std::istream& operator>>(std::istream& stream, BasicString& str)
    	{
    		stream.seekg(0, stream.end);
    		int size = stream.tellg();
    		stream.seekg(0, stream.beg);
    
    		if (str.buffer != nullptr)
    			delete[] str.buffer;
    
    		str.size = size;
    		str.buffer = new char_type[size + 1];
    		stream.read(str.buffer, size);
    
    		return stream;
    	}
    

    Ich habe auch eine eigene String-Klasse und möchte den operator>> überladen. Wenn ich jetzt aber sowas schreibe:

    BasicString<char> str;
    std::cin >> str;
    

    wird der Code einfach ausgeführt, ohne dass ich im Konsolenfenster die Chance dazu habe etwas einzugeben. Logischerweise wird dann auch nichts vom Stream gelesen.

    Weiß da jemand weiter?

    Grüße



  • seekg und tellg funktionieren nicht mit der Konsole.
    Es gibt leider keine (plattforumunabhängige und afaik auch keine plattformabhängige) Möglichkeit im Voraus zu ermitteln, wie viele Zeichen eingegeben wurde.
    Das einzige was du machen kannst ist Zeichen für Zeichen einzulesen* und in einen Buffer zu pushen, wenn der voll ist, einen größeren anfordern und rüberkopieren.
    Und das ist genau das, was std::vector und push_back() machen.
    Nachdem alles eingelesen wurde, kannst du es dann in deinen String kopieren.

    *Nur, wenn peek auch wirklich sagt, dass da ein Zeichen ist, ansonsten liest der für immer ein (auf der Konsole).



  • Danke an alle. Jetzt funktioniert es 👍

    std::ifstream &operator>> (std::ifstream &is, CString &pStr)
    {
        // Max. 128 Zeichen
    
        pStr.str = new char[128];
        is.getline(pStr.str, 128);
    
        return is;
    }
    

Anmelden zum Antworten