Frage zu Zeiger



  • Hi!

    Wir nehmen gerade in der Schule Zeiger in C++ durch und unser Lehrer hat uns folgende Aufgabe gestellt:

    Es soll ein Datenpacket gebaut werden (ohne klassen oder so, das haben wir noch nicht.) das aus einem Array von chars besteht, genannt "byte_t". Dieses Array ist in 3 Bereiche aufgeteilt:

    1x Kennung der Daten (3 Byte für "str", "int" oder "flt" usw.)
    1x Länge der Daten (4 byte size_t)
    1x Die daten selbst (n byte)

    Soweit sogut, die Kennung setzen und die Daten reinkopieren und auslesen ist kein Problem, aber wie bekomme ich einen size_t in ein char-Array an die Position 3 bis 7?

    Hier der Code an dem ich gerade arbeite:

    #include <stdio.h>
    #include <string.h>
    
    // Aufbau eines Datenpackets:
    //
    // ---------------------------------------------------------------------------
    // |  3 Byte   |  4 Byte           |  n Byte      .......................... |
    // |  Kennung  |  Länge der Daten  |  Die Daten   .......................... |
    // ---------------------------------------------------------------------------
    typedef unsigned char byte_t;
    
    byte_t* erstelle_daten (char* inhalt)
    {
        size_t laenge = 0;
        laenge += 3; // Kennung der Daten
        laenge += 4; // Länge der daten als size_t
        laenge += strlen (inhalt);
    
        // ergebnis erstellen.
        byte_t* ergebnis = new byte_t[laenge];
        memset (ergebnis, 0, laenge);
    
        // Kennung setzen
        ergebnis[0] = 's'; ergebnis[1] = 't'; ergebnis[2] = 'r';
    
        // ###################################################
        // TODO:
        // Länge setzen.
        // ###################################################
    
        // daten einfügen (ohne \0!)
        size_t daten_anfang = laenge - strlen (inhalt);
        memcpy (ergebnis + daten_anfang, inhalt, strlen (inhalt));
    
        return ergebnis;
    }
    
    void zeige_daten (byte_t* daten)
    {
        // ist es ein string?
        if (daten[0] == 's' && daten[1] == 't' && daten[2] == 'r')
        {
            // zur länge der daten gehen:
            daten += 3; 
    
            // Länge der daten auslesen.
            size_t laenge = 0;
            // ###################################################
            // TODO: wie machen?
            // ###################################################
    
            // zu den daten gehen.
            daten += 4;
    
            // - puffer für die ausgabe erstellen. (+1 wegen \0!)
            // - string aus dem datenpacket holen und terminieren.
            // - ausgeben und puffer freigeben.
            char* puffer = new char[laenge + 1];
            memcpy (puffer, daten, laenge);
            puffer[laenge] = '\0';
    
            printf ("inhalt des puffers: %s\n", puffer);
            delete [] puffer;
        }
    }
    
    int main ()
    {
        byte_t* daten = erstelle_daten ("hallo welt!");
        zeige_daten (daten);
        delete [] daten;
    }
    

    Muss ich den size_t in 4 Bytes aufteilen und dann setzen? Wie mache ich das am Besten?

    Viele Grüße, euer C++ Zeiger-Neuling.



  • Du könntest es auch mit memcpy machen. Ist dann aber nicht mehr plattformunabhängig. Da dein Lehrer aber anscheinen davon ausgeht, dass size_t immer 4 byte groß ist (was auf 64 Bit Systemen nicht stimmt), ist plattformunabhängig wahrscheinlich egal.



  • C++ Zeiger-Neuling schrieb:

    Soweit sogut, [...] aber wie bekomme ich einen size_t in ein char-Array an die Position 3 bis 7?

    Du hast also das:

    std::size_t Value = 123456789;
    char Array[8] = {};
    

    Dann kannst du zum Beispiel casten:

    *reinterpret_cast<std::size_t*>(Array + 3) = Value;
    

    Oder byteweise kopieren:

    memcpy(Array + 3, &Value, sizeof(Value));
    

    Man könnte das im Weiteren auch über union lösen, das wäre allerdings etwas umständlich. Gibt es eigentlich einen Grund, wieso ihr keine struct s nehmt? Du kannst das Padding bei den meisten Compilern auch auf 1 Byte minimieren.



  • hi!

    dank dir, für die ausführliche Hilfe Nexus! Auch dir deractionhit!

    Ich habe es nun mit dem memcpy gemacht, das halte ich für die beste Lösung zum setzen der Daten. 🙂 Zum auslesen der Daten habe ich dies hier gemacht:

    size_t laenge = *reinterpret_cast<size_t*>(daten + 3);
    

    läuft echt super! Danke euch beiden noch mal. 🙂


Anmelden zum Antworten