Hexstream in Hexpaare zerlegen



  • Guten Tag,

    ich bin noch nicht sehr begabt in dem Gebiet C, deswegen hab ich mir hier und dem Rest auf Google heute schon den Wolf gesucht. Evtl. kann mir hier JEmand ja helfen 🙂

    Undzwar versuche ich in meinem C Programm von einem Seriellen Com Port einen Hex stream, dessen Länge unbekannt ist, in einem Array zu Speichern und den kompletten stream dann in die einzelnen Hexwerte zu zerlegen um diese verarbeiten zu können.

    Beispiel:

    Der Comport sendet " F45612A0B2FE "

    Nun möchte ich einzelne Hexwerte manipulieren können, also brauche ich eine Schleife die immer die Zahlen Paare durchforsten kann.

    Dementsprechend Brauche ich ja dann "F4", "56", "12" etc.

    Ich kenne nur keine Möglichkeit aus dem Array dann F und 4 zu nehmen und F4 daraus zu machen und so weiter

    Hoffe mir kann geholfen werden 😃

    Gruß


  • Mod

    Ich bin mir nicht sicher, ob ich dich richtig verstehe, was du da bekommst, und was du am Ende haben möchtest.

    Bezüglich der Eingangsdaten:
    Bekommst du da eine Zeichenkette, also wirklich "F45612A0B2FE" ?
    Oder kommt das als Zahlenwerte, die du hier bloß der Lesbarkeit wegen als Zeichenkette angegeben hast, also 244-86-18-160-178-254?

    Bezüglich der Ausgangsdaten:
    Möchtest du nun eine Folge von Zeichenketten, also "F4"-"56"-"12"-"A0"-"B2"-"FE" ? Oder eine Reihe von Zahlen, also 244-86-18-160-178-254?



  • Also das C-Programm soll Eine Zeichenkette aus Hex Werten von einem Comport aus einlesen können und über einen anderen Port wieder ausgegeben werden.
    Doch müssen die Ausgegebenen Werte teilweise verändert werden.

    Mir geht es nur darum, es kommt ja ein ganzer Datensatz als Stream rein und das was ich da als Beispiel geschrieben hab war wirklich nur ein Beispiel.
    Es könnte also auch nur 1180 reinkommen, also Zwei Werte 11 und 80.

    Aber für die weitere Funktion im Programm müsste ich den ganzen Datensatz immer in die eigendlichen Werte auftrennen damit ich diese verarbeiten kann.

    Ich habe also ein großes char Array, dass den Stream vom Comport1 speichert.

    Dann brauche ich eine Funktion ( oder Schleife) die immer Zwei Werte aus dem Array nimmt ( 0-F ) und diese als einen Wert speichert, der evtl verarbeitet wird
    um es dann per Ausgabe Array zu Comport 2 zu schicken.

    Mir geht es speziell erstmal darum wie ich es angehe die Hex Kette in Ihre dort enthaltenen Werte auftrenne

    Sitze schon den ganzen Tag dran, fällt mir schon schwer mich vernünftig ausdrücken zu können 😃



  • Ein String ist kein Stream.

    Brauchst du überhaupt den Gesamtstring, reichen nicht auch einzelne 2-Zeichen Gruppen? Das würde den Aufwand stark reduzieren.

    sscanf ist die Lösung (quasi ein Stringstream in C):

    int hex2int(const char *s,unsigned *i)
    {
    	int n, z = 0;
    	while( 1==sscanf(s+z*2,"%2x%n",i+z,&n) && n==2 )
    		++z;
    	return z;
    }
    ...
    unsigned *u;
    int z = hex2int("0815abCDFFFFFFFFFFFFFFFFFFF",u=(unsigned[1000]){0});
    


  • Danke schonmal für die Lösung werde mich da mal reinarbeiten 😃

    Im Endeffekt geht es darum, der Comport sendet Befehle ( Deswegen kann die HEXkette auch immer anders sein).

    Die Kette müsste immer in Ihre Werte aufgespalten werden, die ich dann durch eine Switchanweisung jage um sie evtl. zu verändern (nein es ist nicht möglich, dass der sendende Comport gleich die richtigen Werte schickt 🙂 )



  • Lucient schrieb:

    Ich kenne nur keine Möglichkeit aus dem Array dann F und 4 zu nehmen und F4 daraus zu machen und so weiter

    Da helfen u.a. logische Operationen. Du holst dir das erste Byte und machst AND-Verknüpfung mit 11110000.
    Später schiebst du z.B. F entsprechend nach links und "addierst" die 4 wieder dazu.



  • Lies 2 Zeichen vom Comport, Mach daraus ein Byte, verändere es und schreibe es wieder raus.
    Und dann von vorne.



  • DirkB schrieb:

    Lies 2 Zeichen vom Comport, Mach daraus ein Byte, verändere es und schreibe es wieder raus.
    Und dann von vorne.

    Nach soeiner Methode hab ich ja gefragt 🙂



  • Du kannst dir einen Zeiger auf short nehmen und dem dann die adresse des array zuweisen und dann immer auf jeweils 2 byte zugreifen, wenn du ihn inkrementierst.



  • Wade1234 schrieb:

    Du kannst dir einen Zeiger auf short nehmen und dem dann die adresse des array zuweisen und dann immer auf jeweils 2 byte zugreifen, wenn du ihn inkrementierst.

    Hast du dafür nen Ansatz, wie ich mir das vorstellen kann ?



  • Wade1234 schrieb:

    Du kannst dir einen Zeiger auf short nehmen und dem dann die adresse des array zuweisen und dann immer auf jeweils 2 byte zugreifen, wenn du ihn inkrementierst.

    Sorry, aber das verstehe ich ja kaum.



  • Lucient schrieb:

    DirkB schrieb:

    Lies 2 Zeichen vom Comport, Mach daraus ein Byte, verändere es und schreibe es wieder raus.
    Und dann von vorne.

    Nach soeiner Methode hab ich ja gefragt 🙂

    Wo hast du denn da das Problem?



  • Bekommst du wirklich ascii zeichen also "F' und "1" usw. Oder zeigt dir dein testprogramm einfach nur die daten in hex an?

    Verstehst du meine frage 100%?

    Es ist eher unueblich das hex zeichenfolgen ueber die leitung kommen und die richtige antwort ist davon abhängig wie es genau ist



  • DirkB schrieb:

    Lucient schrieb:

    DirkB schrieb:

    Lies 2 Zeichen vom Comport, Mach daraus ein Byte, verändere es und schreibe es wieder raus.
    Und dann von vorne.

    Nach soeiner Methode hab ich ja gefragt 🙂

    Wo hast du denn da das Problem?

    Wie gesagt, bin auf der C Ebene halt ein Neuling. Mir fällt es noch nicht so leicht eben eine Funktion zu schreiben. Bin auch noch daran, die Funktion von Wutz genau zu verstehen, wie ich die bei mir einsetzten könnte 😕 🙂 .

    Bekommst du wirklich ascii zeichen also "F' und "1" usw. Oder zeigt dir dein testprogramm einfach nur die daten in hex an?

    Verstehst du meine frage 100%?

    Es ist eher unueblich das hex zeichenfolgen ueber die leitung kommen und die richtige antwort ist davon abhängig wie es genau ist

    Wir haben die Comports mitgelogged und es sind wirklich einzelne Hexbefehle in einer Reihe aufgestellt.

    Bsp.: Com 1 sendet " 5931, also 0x59 , 0x31 . Die 0x werden nicht mitgelogged oder auch garnicht erst gesendet, kann ich jetzt leider nicht genau sagen 😕 " Com 2 antwortet darauf mit " 5159" Das sind alles erstmal nur Steuerbefehle, worauf dann ein ganzes Datenpaket folgt wie z.B. "FB31F0102020202020FB31F0 ... usw."

    Mir geht es jetzt auch erstmal nur darum was Com1 Sendet, mit den Steuerantworten befasse ich ich später.

    Nun dachte ich mir ich lasse den Comport erstmal in ein großes Eingangs Array schreiben und jage dieses Array Stück für Stück durch eine Switch Anweisung, die einzelne Befehle manipulieren soll, so soll aus "43 also 0x43" dann "0x1B, 0x43,0x00" werden.

    Die Switchanweisung bekome ich glaube noch selber hin 😃 aber ich hänge gerade bei der Mehtode immer wirklich nur 2 Werte aus dem Array zu nehmen und diese zu einer Hexzahl zu machen.

    Vllt. denke ich auch einfach nur zu kompliziert 😕 😃



  • Hexbefehle

    gibt es genau so wenig wie If-Schleifen - das sind ein paar Bits in Hexadezimal-Darstellung, manche Terminal-Programme können z.B. den Inhalt auch dezimal oder binär Ausgeben

    Bsp.: Com 1 sendet " 5931, also 0x59 , 0x31 . Die 0x werden nicht mitgelogged oder auch garnicht erst gesendet, kann ich jetzt leider nicht genau sagen 😕 " Com 2 antwortet darauf mit " 5159" Das sind alles erstmal nur Steuerbefehle, worauf dann ein ganzes Datenpaket folgt wie z.B. "FB31F0102020202020FB31F0 ... usw."

    0x ist ein Postfix um (z.B. in der Programmiersprache oder Ausgabe) klar zu machen zu das die folgende Zahl in Hex-Notation ist, Beispiele:
    C/C++ => 0x33
    Assembler => 33h
    QBasic => &H33

    das wird nie gesendet - höchstens ein Idiot sendet/schickt Werte sinnfrei als Hex-Zeichenfolgen (also direkt lesbar) kodiert

    wenn du Hochkommas verwendest denke alle da werden Zeichenketten geschickt - lass das am besten

    schreibt lieber

    "das ist eine Zeichenkette"

    ansonsten

    {FB, 31, F0, 10, ...}

    oder

    {0xFB, 0x31, 0xF0, 0x10, ...}

    oder

    "\xFB\x31normaler Text\F0\x10..."

    char* paket = "\xFB\x31normaler Text\F0\x10...";

    damit sagst du klar und deutlich aus was von deinen Bytes "lesbar"
    und was "binär" ist

    FRAGEN

    1. du willst also ein Protokoll nachbauen - von welchem Gerät denn?

    2. normalerweise gibt es längen-Angaben am Anfang wie lange du lesen muss bis ein Paket fertig ist, fixe Paketlängen, oder ein Terminate-Char ist vereinbart das ein Paket-Ende markiert kommt auf die Protokoll-Implementierung an

    3. Stell hier mal so ein Log rein - mit Code-Tags dann sehen wir besser was du vor hast



  • Prefix sorry



  • Der Hexstring ist nur eine Darstellungsform, d.h. es werden binär die Daten gesendet, d.h. einzelne Bytes (char).
    Du brauchst also nur ein char-Array:

    char buffer[SIZE];
    

    oder eben dynamisch per malloc:

    char *buffer = malloc(SIZE);
    

    wobei SIZE dann eine entsprechende Konstante (oder Variable) ist, welche die Größe angibt.
    Und dann einfach per Schleife die Daten ändern:

    if (buffer[i] == 0x43)
    {
      newbuffer[j++] = 0x1B;
      newbuffer[j++] = 0x43;
      newbuffer[j++] = 0x00;
    }
    


  • DirkB schrieb:

    Sorry, aber das verstehe ich ja kaum.

    ich hab mich auch verlesen bzw. so interpretiert, dass quasi ein bytearray gesendet wird und dann jeweils 2 byte verarbeitet werden sollen. tut mir wirklich leid für die verwirrung.

    Lucient schrieb:

    Wir haben die Comports mitgelogged und es sind wirklich einzelne Hexbefehle in einer Reihe aufgestellt.

    ja das ist meistens so, bzw. diese hexbefehle sind einfach bytes.

    Bsp.: Com 1 sendet " 5931, also 0x59 , 0x31 . Die 0x werden nicht mitgelogged oder auch garnicht erst gesendet, kann ich jetzt leider nicht genau sagen 😕 " Com 2 antwortet darauf mit " 5159" Das sind alles erstmal nur Steuerbefehle, worauf dann ein ganzes Datenpaket folgt wie z.B. "FB31F0102020202020FB31F0 ... usw."

    ja genau so läuft das. irgendwo im programm wird das dann irgendwie interpretiert, aber in der regel schiickst du über den comport keine "hexstrings", sondern binärdaten.

    die 1. frage lautet dann, wie viele bytes breit diese befehle sind. bei einem byte kannst du das dann ganz normal mit char auswerten, bei zwei bytes sind wir dann wieder beim short, bei vier bytes (meistens) beim int usw.

    Nun dachte ich mir ich lasse den Comport erstmal in ein großes Eingangs Array schreiben und jage dieses Array Stück für Stück durch eine Switch Anweisung, die einzelne Befehle manipulieren soll, so soll aus "43 also 0x43" dann "0x1B, 0x43,0x00" werden.

    also unter unix gibt es die funktionen read() und write(), unter windows die funktionen readfile() und writefile(). bei dir muss das auch irgendwie so gehen.
    du übergibst der funktion ein array von z.b. 500 byte und die information, dass 500 byte gelesen werden sollen, z.b. read(com, array, 500).

    wenn das ganze dann erfolgreich war, hast du dein array und kannst mit *(arrayname + index) oder arrayname[index] auf die einzelnen bytes zugreifen.

    Die Switchanweisung bekome ich glaube noch selber hin 😃 aber ich hänge gerade bei der Mehtode immer wirklich nur 2 Werte aus dem Array zu nehmen und diese zu einer Hexzahl zu machen.

    bist du dir sicher, dass du 2 werte haben willst? das wären z.b. 0xffff oder 0x0000, da sind wir dann wieder beim pointer auf (unsigned) short.



  • Lucient schrieb:

    ... aber ich hänge gerade bei der Mehtode immer wirklich nur 2 Werte aus dem Array zu nehmen und diese zu einer Hexzahl zu machen.

    Vllt. denke ich auch einfach nur zu kompliziert 😕 😃

    Du wirst nur ein Byte lesen müssen. Das brauchst du auch nicht wandeln, da es schon der Wert ist

    Wade1234 schrieb:

    also unter unix gibt es die funktionen read() und write(), unter windows die funktionen readfile() und writefile(). bei dir muss das auch irgendwie so gehen.
    du übergibst der funktion ein array von z.b. 500 byte und die information, dass 500 byte gelesen werden sollen, z.b. read(com, array, 500).

    In Standard-C gibt es fread und fwrite



  • Vielen Dank schonmal für die umfangreiche Antworten, die Tipps werd ich zu Herzen nehmen 🙂 .

    Hierbei handelt es sich um ein Schulprojekt, indem man natürlich darauf achten sollte nicht alles aus fremden Quellen zu fischen sondern eher nur Hilfestellungen zu suchen.

    In unserem Projekt soll ein Thermo-Drucker durch einen anderen Thermo-Drucker ersetzt werden. Zur Ansteuerung des neuen Druckers haben wir schon eine WinForm in C# entwickelt. Mein Part ist nun in nativem C ein Programm zu schreiben, dass die Befehle des alten Druckers in die des neuen umsetzt ( Der sendende Automat ist in C programmiert, deswegen hier der C Part).

    Dieses C programm soll später dann in den Automaten implementiert werden sodass je nach genutztem Drucker der Automat das Programm nutzt oder nicht.

    Da in unserer C# Anwendung auch immer in Hex gesendet und Empfangen wird, wollte ich das hier in dieser C Anwendung so beibehalten.

    Nun wollte ich erstmal einhergehen und anfangen das Grundgerüst der Anwendung zu erstellen.

    Zuerst hab ich 2 Arrays angelegt

    char Eingang[];
    char Ausgang[];
    

    Sodass man zur Weiterverarbeitung später nurnoch auf die Beiden Zugreifen braucht.

    Dann eine Switch-Anweisung in der nach bestimmten Befehlen Seitens des Automaten gesucht wird und diese in die Befehle des neuen Druckers umgesetzt werden ( wie Oben schon beschrieben ).

    Nur kam mir dann der Gedanke, dass im {Eingang[]} ne ganze Kette an Werten befinden müsste, die direkt in eins in die Switch Anweisung geladen wird und dementsprechend in die einzelnen Werte zerlegt werden muss.


Log in to reply