Problem mit einem Template [SOLVED]



  • Nun bin ich doch noch über einen Fehler gestolpert, und zwar in copy_to_matrix(), ich hab main nun etwas abgeändert um das zu testen und erhalte ein echt komischen Output, also irgendwas mach ich da falsch.

    template <typename T>
        void copy_to_matrix(T* dBuffer, T** dArray, arrayrange)
        {
            int a, b;
            for(a = 0; a < arrayrange; a++)
            {
                for(b = 0; b < arrayrange; b++)
                {
                    dArray[a][b] = dBuffer[a*b];
                }
            }
        }
    
    int main(int argc, char* argv[])
    {
        int filesize = A::get_filesize("a.txt");
        int tablesize = A::get_tablesize(filesize);
        char** matrix = A::new_matrix<char>(tablesize, tablesize);
        char* buffer = A::load_to_buffer<char>("a.txt", filesize);
        A::copy_to_matrix<char>(buffer, matrix, tablesize);
    
        std::cout << "Filesize: " << filesize << " Byte" << std::endl;
        std::cout << "Tabelle X: " << tablesize << std::endl;
        std::cout << "Tabelle Y: " << tablesize << std::endl << std::endl;
        std::cout << "Buffer: " << std::endl;
        std::cout << buffer << std::endl << std::endl;
        std::cout << "Matrix: " << std::endl;
        for(int a = 0; a < tablesize; a++)
        {
            for(int b = 0; b < tablesize; b++)
            {
                std::cout << matrix[a][b];
            }
            std::cout << std::endl;
        }
        A::delete_buffer<char>(buffer);
        A::delete_matrix<char>(matrix);
        return 0;
    }
    

    Also der dump von buffer ist richtig, der dump von matrix dagegen nicht.

    `

    Filesize: 593 Byte

    Tabelle X: 25

    Tabelle Y: 25

    Buffer:

    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod

    tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At v

    ero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren,

    no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit am

    et, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labor

    e et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et ju

    sto duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus

    est Lorem ipsum dolor sit amet.

    Matrix:

    LLLLLLLLLLLLLLLLLLLLLLLLL

    Lorem ipsum dolor sit ame

    Lrmismdlrstae,cneeu aisig

    Leiudos e ntusicglrs anu

    Lmsdrteceuasgi mn mtonuu

    L mottntace, mrtri a o a

    Lidsenuigr n doiuo eaurem

    Lpl cti amood onua o.re

    Lsreeag m tnueoaa mueeasd

    Lus ucra eil au,maoatuset

    Lmtnae mtiaoa pe toemiun

    L ats,nonlo ra.oa suib te

    Ldeug ou armAetdat naest

    Lo,si ddea aAtjobtgtt ser

    Llci mo ou .ejrmk,atd.d,a

    Lonc ri a,potoman r mie m

    Lregmtuoameadbknsmtsea n

    L elnron a at, m m sdd o

    Lsur i umotstgartmcimmag

    Li sm eauaou tt s i orade

    Lta taa eteintdmesmoeimes

    L iao uoeumba .iadmri s b

    Lasnnor.asi esde daamsdme

    Lmiuu erseutse, gde mrs

    Leg uamedtnetramno esbesd

    Process returned 0 (0x0) execution time : 0.083 s

    Press any key to continue.`

    Also für Ratschäge bin ich echt offen. Auch stell ich mir die Frage wie ich in meinem Namespace, eine Art Variablentyp bauen kann um z.b char** matrix als Bsp. A::Matrix zu schreiben. Templates sind for mich wirklich ein komplett neues Feld:



  • Du solltest dir wirklich dringend mal Klassen ansehen. Tut mir Leid das so sagen zu müssen, aber den Code zu lesen tut weh wenn man weiß was Destruktoren sind. 😉



  • Ich weis schon was Klassen sind im moment gehts mir erstmal darum die Funktionen laufend zu bekommen. Dann kann ich das Ganze immernoch in eine Klasse einkapseln, und btw. lehn dich zurück und schau dir mal den Code aus deiner Aanfangszeit an, und dann bedenke das ich grade mal seit 2-3 Wochen in c++ code, und davor zu 80% nur mit Sriptsprachen gearbeitet habe die nicht über Zeiger verfügt haben und bei weitem nicht so anspruchsvoll mit den Datentypen waren.

    template <typename T>
        void copy_to_matrix(T* dBuffer, T** dArray, int arrayrange)
        {
            bool split = false;
            int a, b, c = 0;
            for(a = 0; a < arrayrange; a++)
            {
                for(b = 0; b < arrayrange; b++)
                {
                    if((split == false)&&(dBuffer[c] != '\0'))
                    {
                        dArray[a][b] = dBuffer[c];
                        c++;
                    }
                    else
                    {
                        split = true;
                        dArray[a][b] = '\0';
                    }
                }
            }
        }
    

    Des Rätzels Lösung, nun sieht der Dump auch so aus wie er aussehen sollte. Bleibt nur noch meine Frage zu den Variablen.



  • Videonauth schrieb:

    Ich weis schon was Klassen sind im moment gehts mir erstmal darum die Funktionen laufend zu bekommen. Dann kann ich das Ganze immernoch in eine Klasse einkapseln, und btw. lehn dich zurück und schau dir mal den Code aus deiner Aanfangszeit an, und dann bedenke das ich grade mal seit 2-3 Wochen in c++ code, und davor zu 80% nur mit Sriptsprachen gearbeitet habe die nicht über Zeiger verfügt haben und bei weitem nicht so anspruchsvoll mit den Datentypen waren.

    Eine Skriptsprache ohne Zeiger, gibt es so etwas?
    Gerade weil C++ so "anspruchsvoll" ist, benutzt man Klassen. Lern was eine Klasse ist und vergiss den new[] -Operator ganz schnell. Du suchst eigentlich vector .



  • Videonauth schrieb:

    Ich weis schon was Klassen sind im moment gehts mir erstmal darum die Funktionen laufend zu bekommen.

    Klassen sind nicht irgendwelcher Syntaxzucker, die werden dein Problem quasi von alleine Lösen, weil alles so viel übersichtlicher wird. Du musst ja nicht gleich alles mit Templates machen. Einfach nur:

    class matrix
    {
      std::vector<std::vector<double>> data_;
    public:
      matrix(std::size_t x, std::size_t y)
        : data_(x, std::vector<double>(y))
      {}
      // ...
    };
    

    Und darauf aufbauen. Ist zwar verdammt langsam etc., aber immerhin ein Anfang. Dein doppeltes Pointer gefrickel ist das schlimmste, unübersichtlichste und gleichzeitig auch noch mehr oder weniger langsamste was man machen kann. Guck dir Klassen an, es lohnt sich. 😉



  • Naja hab das erste part nun mal eingekapselt und umgeschrieben, ich mein ich entwickel mich ja auch weiter mit jeder Zeile Code die ich schreibe, der File Handler sieht nun z.b. so aus:

    class File
        {
            private:
                std::string m_sFilename;
                std::fstream m_fFilestream;
                int m_nFilesize;
            public:
                File()
                {
                }
                File(std::string sFilename)
                {
                    this->m_sFilename = sFilename;
                    this->set_filesize();
                }
                ~File()
                {
                }
                void set_name(std::string sFilename)
                {
                    this->m_sFilename = sFilename;
                    this->set_filesize();
                }
                std::string get_name(void)
                {
                    return this->m_sFilename;
                }
                int get_filesize(void)
                {
                    return this->m_nFilesize;
                }
                void set_filesize(void)
                {
                    this->m_fFilestream.open(this->m_sFilename.c_str(), std::fstream::in | std::fstream::binary);
                    if(this->m_fFilestream.is_open())
                    {
                        this->m_fFilestream.seekg(0, std::fstream::end);
                        this->m_nFilesize = this->m_fFilestream.tellg();
                        this->m_fFilestream.seekg(0, std::fstream::beg);
                        this->m_fFilestream.close();
                    }
                }
                std::vector<char> load(void)
                {
                    std::vector<char> buffer(this->m_nFilesize);
                    this->m_fFilestream.open(this->m_sFilename.c_str(), std::fstream::in | std::fstream::binary);
                    if(this->m_fFilestream.is_open())
                    {
                        this->m_fFilestream.read(&buffer[0], this->m_nFilesize);
                        this->m_fFilestream.close();
                    }
                    return buffer;
                }
                void save(std::vector<char> vBuffer)
                {
                    this->m_fFilestream.open(this->m_sFilename.c_str(), std::fstream::out | std::fstream::binary | std::fstream::trunc)
                    if(this->m_fFilestream.is_open())
                    {
                        this->m_fFilestream.write(&vBuffer[0], vBuffer.size());
                        this->m_fFilestream.close();
                    }
                }
                void save(std::vector<char> vBuffer, bool bTrunc)
                {
                    if(bTrunc == false)
                    {
                        this->m_fFilestream.open(this->m_sFilename.c_str(), std::fstream::out | std::fstream::binary);
                    }
                    if(bTrunc == true)
                    {
                        this->m_fFilestream.open(this->m_sFilename.c_str(), std::fstream::out | std::fstream::binary | std::fstream::trunc);
                    }
                    if(this->m_fFilestream.is_open())
                    {
                        this->m_fFilestream.write(&vBuffer[0], vBuffer.size());
                        this->m_fFilestream.close();
                    }
                }
        };
    

    Frage: gibt es für ...

    this->m_fFilestream.write(&vBuffer[0], vBuffer.size());
    

    ne bessere schreibweise also das man das &vBuffer[] ansers auflösen kann ?
    Komme da mit den tutorials und der Referenz nicht unbedingt weiter.



  • Videonauth schrieb:

    Frage: gibt es für ...

    this->m_fFilestream.write(&vBuffer[0], vBuffer.size());
    

    ne bessere schreibweise also das man das &vBuffer[] ansers auflösen kann ?
    Komme da mit den tutorials und der Referenz nicht unbedingt weiter.

    Nein, gibt es nicht.
    Du hast den Fall vergessen, dass der Puffer leer ist.



  • Oops, danke das hab ich übersehen, das hier ...

    if(this->m_fFilestream.is_open() && vBuffer.size() != NULL)
    

    ... sollte es lösen.



  • Videonauth schrieb:

    Oops, danke das hab ich übersehen, das hier ...

    if(this->m_fFilestream.is_open() && vBuffer.size() != NULL)
    

    ... sollte es lösen.

    NULL ist eigentlich für Zeiger, hier wäre einfach 0 besser.



  • Danke, habs korrigiert. So mal weiter am rest arbeiten, werde dann nochmal Updates posten.



  • Videonauth schrieb:

    Danke, habs korrigiert. So mal weiter am rest arbeiten, werde dann nochmal Updates posten.

    Noch ein paar Tipps:
    - Lass die ungarische Notation. (Dieses int nFoo, std::string sFoo etc.)
    - Schreib nicht this->, es sei denn es ist nötig. (Wenn der Name zweideutig ist.)
    - Schreibe nicht (void), sondern (). Das (void) sieht so nach C aus.
    - Lies dir mal was zu Pointern/Referenzen durch. Das ist jetzt zwar noch nicht soo wichtig, aber es dauert auch nicht lange.
    - Deine File Klasse hat ja nicht mal eine write Methode! Diese solltest du erst machen. Diese save() Methode im allgemeinen könnte man zum flushen nutzen, aber du kannst doch nicht einfach so die Datei schließen!

    PS: Nimm doch ein C-Handle, dann sieht das nicht ganz so sinnlos aus. 😃


Anmelden zum Antworten