Zwei Arraymitglieder zu einem neuen Array zusammenfassen



  • Moin,
    ich versuche aus zwei Arraymitgliedern eine neues Array zu erzeugen und dieses dann aus einer get-Methode zurück zu geben. Dies versuche ich mit einer Liste. mBuf ist ein Attribut der zugehörigen Klasse.

    unsigned char get(void)
    {
    std::list<unsigned char> iBuf;
    iBuf.push_back(mBuf[2]);
    iBuf.push_back(mBuf[3]);
    return iBuf;
    }



  • Deine Funktion erwaret als return Wert einen unsigned char, du versuchst aber eine std::list zurück zu geben. Das wird so nicht kompilieren!



  • Das bedeutet, dass der List Container dafür nicht geeignet ist.
    Welche Möglichkeiten hätte ich denn sonst?



  • Warum bedeutet es denn das? Du könntest die Funktion auch eine std::list zurück geben lassen.

    Wenn es um Arrays geht, würde ich aber eher zu std::vector tendieren, denn ein Array ist halt keine Liste 😉

    Aber allgemein gilt, ein unsigned char ist auch kein Array.

    Wenn ich raten müsste, hast du aus einer Aufgabenstellung falsch abgeschrieben und da steht sowas wie:

    unsigned char* get()
    

    Übrigens, in C++ kannst du das void als Parameter weg lassen.



  • Ich habe jetzt zunächst zwei get-Methoden zur Abfrage genommen. Also für jedes Mitglied jeweils eine. Ist zwar unschön aber läuft erst einmal.



  • Wenn du möchtest, kannst du ja mal deine Lösung (komlett) zeigen, dann könnte man mal drüber schauen, ob die Sinnvoll ist und vielleicht die ein oder andere Anregung geben.

    Wenn ich diesen Thread und den Hex Ausgabe Thread so sehe, fürchte ich, dass du viele Sachen C-typisch löst, die du mit C++ Featuren deutlich einfacher lösen könntest.



  • Also meine HPP Datei sieht so aus:

    #ifndef TLG_HPP_
    #define TLG_HPP_

    #include <iostream>

    class Tlg
    {
    public:
    static const size_t sSIZE = 40;
    typedef unsigned char Buf[sSIZE];

    enum Cmd
    {
    Cmd_Undef = '0',
    Cmd_L = 'L',
    Cmd_S = 'S'
    };

    Tlg();
    ~Tlg();

    void setCmd(Cmd pCmd);
    Cmd getCmd(void) const;
    void setSeqNr(void);
    unsigned char getSeqNr(void) const;
    const unsigned char getMaska(void) const;
    const unsigned char getMaskb(void) const;
    const unsigned char* getBuf(void) const;
    unsigned char* getBuf(void);
    void dumpOn(std::ostream& out) const;

    Buf mBuf;

    };

    inline const unsigned char* Tlg::getBuf(void) const
    {
    return mBuf;
    }

    inline unsigned char* Tlg::getBuf(void)
    {
    return mBuf;
    }

    inline const unsigned char Tlg::getMaska(void) const
    {
    // std::vector<unsigned char> iBuf;
    // iBuf.push_back(mBuf[2]);
    // iBuf.push_back(mBuf[3]);
    return mBuf[2];
    }

    inline const unsigned char Tlg::getMaskb(void) const
    {
    return mBuf[3];
    }

    inline unsigned char Tlg::getSeqNr(void) const
    {
    return mBuf[1];
    }

    inline Tlg::Cmd Tlg::getCmd() const
    {
    return static_castTlg::Cmd(mBuf[0]);
    }
    std::ostream& operator<<(std::ostream& out, const Tlg& rhs);

    #endif /* TLG_HPP_ */


  • Mod

    Darf die Lösung auch in C++ implementiert werden, oder muss es C mit Klassen sein?



  • C++ wäre super



  • Wenn du allen hier ein Gefallen tun möchtest, nutz doch bitte Code tags, damit ist der Spaß deutlich lesbarer!

    Gibt es dazu auch eine cpp? oder ist das Header only?

    Wie ich bereits in meinem letzten Post geschrieben habe, ist void als Parameter in der Funktionsdeklaration unnötig. Das ist nur in C von Bedeutung.

    Offenbar möchtest du verschiedene Werte speichern. Deine beiden Setter sollen offenbar Zahlenwerte nehmen. Für dein Cmd halt chars als Zahlen codiert und bei SeqNr gehe ich mal davon aus, dass das auch eine Zahl werden soll. Warum benutzt du dafür ein überdimensioniertes Char Array?

    Ich persönlich würde den Type Alias anstatt mit "typedef" mit "using" deklarieren, aber das ist wohl Geschmackssache.

    Für mich sieht das ganze so aus, als ob du die Sachen hinterher an eine C-API (Treiber o.ä. ) übergeben möchtest, die das ganze in Form eines unsigned char arrays erwartet.
    Ich würde dir raten, die Daten in der Klasse trotzdem mit ihren entsprechenden Typen zu speichern und das alles erst in das Array zu packen, wenn du die Daten auch wirklich weiterleiten möchtest. Damit kannst du dir den Cast bei deinem Getter sparen.

    Ach, wenn du schon C++ machst und Arrays mit fester Größe hast, würde ich zu sowas raten:

    std::array<unsigned char, sSIZE> mBuf;
    

    Oder wenn es mit alias sein soll:

    using Buf = std::array<unsigned char, sSIZE>;
    Buf mBuf;
    

    Man könnte auch überlegen ob man aust "static const" ein "static contexpr" macht um deutlich zu machen, dass das eine Compilezeit Konstante ist. Dürfte aber keinen großen Unterschied machen, soweit ich weiß.


  • Mod

    marci_du_mont schrieb:

    C++ wäre super

    Dann beschreib mal am besten in Worten, was der Code machen soll, denn man sollte wohl eher Neuschreiben als Verbessern. Da der jetzige Code offenbar nicht macht, was er soll (sonst würdest du schließlich nicht fragen), wäre es besser, wenn du beschreibst, was du erreichen möchtest, anstatt dass wir uns aus dem falschen Code zusammenreimen, was wohl gemeint sein könnte.



  • Ich möchte einfach nur eine get-Methode haben dir mir aus mBuf das Element 2 und 3 in eine neue Variable speichert, so dass ich nur eine getMask-Methode habe.

    Das void als Inputparameter schreibe ich gerne rein, um für mich eine bessere Übersichtlichkeit zu haben.


  • Mod

    Ich meinte: Was soll Tlg machen? Denn in C++ würde man Tlg von Anfang an niemals auch nur ansatzweise so implementieren wie hier. Deine Frage ist nur ein Symptom des eigentlichen Problems, denn das Zusammenfügen verschiedener Datenstrukturen wäre in richtigem C++ kein Problem.



  • Ich schreibe eine Server Client Anwendung.
    Die Klasse Tlg ist eine Klasse um ankommenden Telegramme einer anderen Klasse, zu bearbeiten. Die ankommenden Telegramme werden durch den Aufruf einer Instanz der Klasse in mBuf dieser Instanz abgelegt. Die Länge der Telegramme ist fest definiert. Die Get-Methoden werden dann bei Telegrammempfang durch diese Instanz aufgerufen und der Inhalt von mBuf weiter verarbeitet.



  • Ok, vorrausgesetzt die Client Server Kommunikation läuft, bekommst du deine Daten irgendwo her. Was für Daten sind das? In welcher Form liegen die vor? Wie willst du die weiter verarbeiten?



  • Moin,

    also die Anwendung läuft ohne weiteres. Das Telegramm hat zum Beispiel folgenden Inhalt:

    pTlg.mBuf = {'L', 0x02, 0x1e, 0x11, 0xff, 00, 00 ,00 , usw. Länge = 40}

    Inhalt Eins dient zur Identifikation der Telegrammart.
    2 und 3 sind Inhalte, die ich weiter über eine Websocket Verbindung, im JSON Format, weiter an einem Client (Browser) versenden will. Daher will ich diese beiden Elemente mit einer get-Methode herausziehen und mit JSON formatieren.



  • Hi,

    sorry, ich hatte gestern recht viel um die Ohren und keine Zeit groß was zu schreiben.

    Du hast pro Stelle ein Byte, nutzt aber verschiedene Repräsentationen für die Stellen. (Zeichen, Hex und evtl noch anderes?)

    Ich weiß immer noch nicht ob ich wirklich alles, was deine Klasse machen soll verstanden habe, aber wenn es darum geht den Eingabe Buffer zu parsen und als JSON wieder auszugeben, würde ich wahrscheinlich den Stream Operator in beide Richtungen für die Klasse definieren. Einmal nimmt der ein unsigned char array und parst das. Und einmal in Ausgabe Richtung, da wird das fertige JSON als String (?) zurückkgegeben.

    Die interne Repräsentation in der Klasse würde ich so wählen, dass die Daten direkt in dem Format vorliegen, in dem ich sie brauche. Die Hex-Zahlen würde ich zum Beispiel direkt als String in der Klasse speichern. Dann kannst du die für deine Ausgabe direkt verarbeiten.


Anmelden zum Antworten