benutzerdefinierter << - Operator



  • na dann guck ma, was er im copy-ctor macht (und was nicht).

    debugger und so ^^



  • Hm, ehrlich gesagt mit debuggern kenn ich mich nicht so aus (leider), aber hier ist mein Versuch des Kopier-Konstruktors... :

    CharSet::CharSet(const CharSet& c)
    {
        int i;
        for(i=0; i<ARRSIZE; i++)
            data[i] = c.data[i];
    }
    

    Ich habe auch bei der Ausgabe mit hereingepfuscht, dass er alle 8 Int's der Arrays mit ausgeben soll, die sind identisch:
    cs1:

    0
    0
    16777230
    0
    0
    0
    0
    0
    

    cs4 (die Kopie) :

    0
    0
    16777230
    0
    0
    0
    0
    0
    

    Es sollte wirklich identisch sein! Er nutzt auch den Kopier-Konstruktor, das habe ich auch überprüft. Warum habe ich immer noch meine verbuggte Ausgabe?! Ich checks nicht, ehrlich!



  • hmm.. ich fand eigtl auch, dass es ganz brauchbar aussah ^^
    wenn du mir nen compilierbares bsp schickst, was net in mehrere files unterteilt ist (also einmal copy&paste), dann guck ich mal - bin nur zu faul, das gerad alles selbst zu tippen ^^

    bb



  • alles klar 🙂
    hab hier eins zusammenkopiert, da sind zuerst die ausgaben drin, was die einzelnen Ints in den arrays für werte haben, und unten dann die Ausgabe.

    #include <iostream>
    using namespace std;
    #define COUT(par) (cout << #par " = " << (par) << '\n')
    
    enum { NUMCHARS = 256 };               // Umfang des Zeichensatzes
    enum { INTBITS = sizeof(int) * 8 };    // Bits pro int
    enum { ARRSIZE = NUMCHARS / INTBITS }; // Arraygröße
    
    class CharSet
    {
        private:
            int data[ARRSIZE];
        public:
            CharSet(const char *n=NULL);
            CharSet(const CharSet& c);
            bool contains(const char n) const;
            ~CharSet() {};
    };
    ostream& operator<<(ostream& os, const CharSet& c);
    
    int main(void)
    {
       const CharSet cs1("ABCX");
       const CharSet cs2("CDY");
       const CharSet cs3("BC");
       const CharSet cs4(cs1);
       COUT(cs1);
       COUT(cs2);
       COUT(cs3);
       COUT(cs4);
       return 0;
    }
    
    CharSet::CharSet(const char *n)
    {
        int bit, i, j, shift;
        for(i=0; i<ARRSIZE; i++)
            data[i] = 0;
        for(j=0; j<(signed)strlen(n); j++)
        {
            bit = 1;
            shift = n[j]%INTBITS;
            bit = bit << shift;
            data[n[j]/INTBITS] |= bit;
        }
            for(i=0; i<ARRSIZE; i++)
                cout << data[i] << "\n";
    }
    
    CharSet::CharSet(const CharSet& c)
    {
        int i;
        for(i=0; i<ARRSIZE; i++)
        {
            data[i] = c.data[i];
            cout << data[i] << "\n";
        }
    
    }
    
    ostream& operator<<(ostream& os, const CharSet& c)
    {
        int i, j=0;
        char arr[NUMCHARS];
        for(i=0; i<NUMCHARS; i++)
            if(c.contains((char)i))
                arr[j++] = i;
        arr[j] = '\0';
        return os << arr;
    }
    
    bool CharSet::contains(const char n) const
    {
        int i, shift;
    
        i = n/INTBITS;
        shift = n%INTBITS;
        if(data[i]==0)
            return false;
        else
        {
            if( ((data[i] >> shift) & 1) ==1 )
                return true;
            else
                return false;
        }
    }
    

    (Das schlimmste wär jetzt, wenns bei dir fehlerfrei läuft...)
    Vielen Dank fürs ausprobiern!!
    ~flip



  • also zu erst mal:
    der fehler tritt _immer_ auf - ich guck auch gleich mal, wieso genau - davor aber noch was: wenn du den ctor mit const char* x = NULL deklarierst, musst du (bevor du strlen aufrufst schon mal gucken, ob du nen gültigen pointer hast, weil strlen nich auf null prüft) - wenn ich das jz so sehe, wohl doch nen extra ctor für den fall bauen...

    also in etwa so:

    charset()
    {
     nullfkt();
    }
    
    charset(const char* val)
    {
     nullfkt();
    
    for(j=0; j<(signed)strlen(n); j++)
        {
            bit = 1;
            shift = n[j]%INTBITS
    }
    

    das der fehler immer auftritt liegt daran, dass die contains() fkt nicht richtig funktioniert...
    gibt mehrere (mögliche) gründe dafür:
    - char ist nicht zwangsläufig auch signed -> du kannst eben nich einfach von nem int auf nen char casten -> bin mir nicht sicher, in wie fern man rumcasten kann, da ich selbst eigtl fast keine casts brauche

    oder was noch wahrscheinlicher ist
    - deine shift-operation is iwie falsch, allerdings kann ich da auf den ersten blick nichts erkennen...

    bb

    edit:
    ok - war wirklich das problem mit dem cast...

    ostream& operator<<(ostream& os, const CharSet& c) 
    { 
        char i, j=0;
        char arr[NUMCHARS]; 
        for(i=0; i!=-128+NUMCHARS; i++)
    	{
            if(c.contains(i)) 
                arr[j++] = i;
    	}
        arr[j] = '\0'; 
        return os << arr; 
    }
    

    funktioniert...
    ich würd jz (wenn ich soetwas komisches machen würde) iwas mit numeric_limits<char>::min()+NUMCHARS machen, denk ich... allerdings müsste man davor halt noch nen assert machen, dass NUMCHARS nicht größer ist, als betrag(min_char) + betrag(max_char)...

    bb



  • Also ich vermute du hast recht, dass die shift-Operator-Funktion falsch ist. Ich habe eben doch mal einen Versuch mit dem Debugger gestartet, und die Schleife in der Operator-Fkt. (Zeile 74) Step für Step durchgetackert. Er hat auch alles schön gemacht und in arr reingeschrieben, aber auf einmal (so bei ca. 100), wo er eigentlich keine "1"er mehr finden dürfte, waren da auf einmal welche!



  • Ah! wahnsinn, es geht!!
    sitze seit fast 24 stunden da dran!!
    Vielen DANK! Aber warum er da so einen Mist macht, ist mir immer noch nicht ganz klar ...



  • siehe edit ^^



  • Ja, wie gesagt, es läuft!

    Aber:
    Im Grunde läuft er doch jetzt nur bis 128! Weil -128+NUMCHARS(=256) = 128. Aber das Array data hat doch 8x32=256 bits. Bin ich da nicht am "mogeln", wenn ich eigentlich nur bis 128 abfrage?



  • huch xD hatte net mehr an die 0 gedacht xD
    japp, du schummelst 😃

    der cast is au net das eigtl problem, weil er dann ja nat. nur die reihenfolge vertauscht...
    also 0,1,2,...,126,127,-128,-127,...,-1

    jedenfalls geht das hier nicht (und er probiert nicht alle zeichen durch sondern lässt das letzte weg):

    #include <limits>
    
    ostream& operator<<(ostream& os, const CharSet& c) 
    { 
        char i; size_t j=0;
        char arr[NUMCHARS]; 
    	for(i=std::numeric_limits<char>::min(); i!=std::numeric_limits<char>::max(); i++)
    	{
            if(c.contains(i)) 
                arr[j++] = i;
    	}
        arr[j] = '\0'; 
        return os << arr; 
    }
    

    also wirst du mal suchen müssen, was du beim shiften falsch machst 😛

    bb



  • hey,
    ich hab nochmal geschaut, aber ich find nix mehr ..
    ich denk ich wackel mal so damit hin zu meinem prof, es läuft ja im Grunde. soll der mir mal erklären was da noch falsch ist. So!

    Vielen Dank nochmal!!

    Gruß, flip


Anmelden zum Antworten