Parsen
-
Ausgeben lassen tut sich nix nach strncpy oder sscanf.
Liegt das nicht daran das buffer ein Pointer ist?
-
Dann gib doch mal als Hex-Werte aus:
hexout(fins_response, 28); hexout(buffer, 28);
void hexout(void *mem, size_t anz) //ungetestet { unsigned char *m = mem; size_t i; for(i=0; i<anz; i++, m++) { printf("%02x ", *m); if (i%16 == 15) putchar('\n'); } if (i%16 != 0) putchar('\n'); }
-
Ich habe bereit eine Funktion die die Hexwerte und die übersetzung ausgibt:
void PrintData (unsigned char* data , int Size){ int i , j; char fins_response[4000]; for(i=0 ; i < Size ; i++) { if( i!=0 && i%16==0) //if one line of hex printing is complete... { printf(" "); for(j=i-16 ; j<i ; j++) { if(data[j]>=32 && data[j]<=128) printf("%c",(unsigned char)data[j]); //if its a number or alphabet else printf("."); //otherwise print a dot } printf("\n"); } if(i%16==0) printf(" "); printf(" %02X",(unsigned int)data[i]); if( i==Size-1) //print the last spaces { for(j=0;j<15-i%16;j++) { printf(" "); //extra spaces } printf(" "); for(j=i-i%16 ; j<=i ; j++) { if(data[j]>=32 && data[j]<=128) { printf("%c",(unsigned char)data[j]); } else { printf("."); } } printf("\n" ); } } }
Wenn ich den buffer und die Länge übergebe funktioniert das wunderbar.
-
Ok, aber was für Werte stehen da?
-
Folgende Ausgabe ergibt sich daraus:
links steht die Hex-Zeichenkette und links das ganze übersetzt in normalen text (Ascii):Die ganze Hex-Zeichenkette muss ich nun parsen / zerlegen, sodass letztendlich mehrere Strings existieren wo jeweils immer ein Bruchteil drin steht.
Deshalb steck ich nun fest wie ich die ganze Hex-Zeichenkette in einen String oder ein normales char-Element bzw char-Array umwandle. Danach kann ich ja das ganze Zerlegen wie in den ersten Posts beschrieben ( mit sscanf oder strncpy)
-
Oje, ich denke du hast weder Arrays noch Zeiger noch C-Strings verstanden.
Welche Daten (von der Grafik) brauchst du denn.
Da das zweite Element gleich eine 0 ist, kommst du da weder mit strncpy noch mit sscanf oder mit printf weiter, da das alles Funktionen sind, die mit C-strings arbeiten.(Stichwort: Nullterminierung)
Die Hexdarstellung ist nur fuer den Menschen, intern ist alles binaer. Da brauchst du nichts umwandeln.
Du kannst direkt auf jedes Element des Arrays/Speichers zugreifen.
puts(buffer+14); //oder char att1[2], att2[4], att3[4]; sscanf(data + 14, "%2c%4c%4c", att1, att2, att3);
-
Du hast also Binärdaten - und keine Hex-Zeichenkette!!!
Um die Binärdaten zu parsen oder einzelnen Teile daraus zu extrahieren, nimm die Funktionen memcmp() bzw. memcpy().
-
Ah, ich verstehe. Wie könnte sowas genau aussehen?
Gruß
-
tooony schrieb:
Ah, ich verstehe. Wie koennte sowas genau aussehen?
Das haengt auch davon ab, was die Attribut bedeuten und wo und wie du sie auswerten willst.
Sind dasint
- odershort
-Werte oder stehen dieunsigned char
fuer sich alleine.
Sind alle Attribute vom selben Typ?
Brauchst du die Werte spaeter nochmal zusammen?
-
Die einzelnen Attribute sollen den Hex-Code so wie es in der Grafik (linker teil) ist beinhalten (ohne Leerzeichen).
Alle Attribute werden dann vom Source-Code in einer E-Mail weitergesendet. Deshalb wäre es vorteilhaft wenn die einzelnen Attribute als einfache Zeichenketten vorliegen.
Sind das int- oder short-Werte oder stehen die unsigned char fuer sich alleine.
Was meinst du damit? Ich steh da grade bisschen auf dem Schlauch.
Die ankommenden Daten am Socket werden mit folgendem definiertem buffer aufgenommen:
unsigned char *buffer = (unsigned char *) malloc(65536);
-
tooony schrieb:
Deshalb wäre es vorteilhaft wenn die einzelnen Attribute als einfache Zeichenketten vorliegen.
Was soll denn das für eine Zeichenkette sein, die aus zB der ersten Reihe der Hex-Werte in Deiner Grafik besteht? Wie Du rechts sehen kannst, sind doch da nur zwei 'echte' Zeichen drin: B_
-
tooony schrieb:
Die einzelnen Attribute sollen den Hex-Code so wie es in der Grafik (linker teil) ist beinhalten (ohne Leerzeichen).
Alle Attribute werden dann vom Source-Code in einer E-Mail weitergesendet. Deshalb Waere es vorteilhaft wenn die einzelnen Attribute als einfache Zeichenketten vorliegen.
Ah, neue, nicht unwichtige Informationen.
Dann schreib sie mit sprintf in einen String (Array).tooony schrieb:
Sind das int- oder short-Werte oder stehen die unsigned char fuer sich alleine.
Was meinst du damit? Ich steh da grade bisschen auf dem Schlauch.
Das koennten ja auch Angaben z.B fuer ein Bild sein. (Breite, Hoehe, Farbtiefe...)
Dann wuerden mehrere Bytes zusammengehoeren.// Schreibt anz Bytes aus mem als Hexwerte in den Speicher ab text, der fuer len Zeichen Platz hat // Wenn der Platz nicht ausreicht, wird NULL zurueckgegeben, sonst text. char * hex2string(char *text, size_t len, void *mem, size_t anz) //ungetestet { unsigned char *m = mem; char *t = text; size_t i; for(i=0; i<anz; i++, m++) { if (text+len >= t+4) // " HExzoffer, ein Leerzeichen und die '\0' return NULL; t += sprintf(t, "%02x ", *m); } return text; }
-
Danke für deine Antwort. Im Goßen und ganzen versteh ich was deine Funktion macht, aber ich bekomm sie nicht angewandt, geschweige denn eine Ausgabe.
Wie muss ich diese Funktion nun auf meinen fall anwenden?
EDIT:
hab das ganze jetzt folgendermaßen gelöst:
for (ia = 0 ; ia < data_size ; ia++) { pos += sprintf(pos, "%02X", buffer[ia]); } printf("%s\n", buf);
-
tooony schrieb:
Danke fuer deine Antwort. Im Groszen und ganzen versteh ich was deine Funktion macht, aber ich bekomm sie nicht angewandt, geschweige denn eine Ausgabe.
Wie muss ich diese Funktion nun auf meinen fall anwenden?
Bei deinem Beispiel von 10:16:01 14.11.2013
char fins_response[500]; hex2string(fins_response, 500, buffer,28); printf("%s\n", fins_response);
-
Danke Für deine Antwort! Leider bringt mich dies wieder zu einem neuen Problem:
Ich sende und empfange periodisch (z.B. aller 30 Sekunden) Daten an einem Socket.
Diese Daten wandle ich als Hex-Zeichenkette in einen String um mit deiner Funktionen oder damit:for (c = 0 ; c < data_size ; c++) { pos += sprintf(pos, "%02X", buffer[c]); }
anschließend nehme ich die Zeichenkette mit sscanf auseinander und weise die Inhalt jeweils den entsprechenenden Variablen (char) zu.
Nun zu meinem Problem:
Da die ganze Sache periodisch passiert: Wie kann ich diese Variablen (char) überschreiben.
Wenn ich das Programm ausführe klappt dies einmal und dann stoppt das Programm.Gruß
-
Ich verstehe nicht, was du meinst. Zu wenig Informationen.
Du hast ein Problem beim scanf und zeigst den Code mit dem printfEin Programm von dir verschickst die Daten (als Hexcode) per Email.
Und der Empfänger (auch ein Programm von dir) wandelt den Hexcode wieder in binäre Daten zurück.
Soweit richtig?
-
Ich hol mal bisschen weiter aus:
Es exisitert eine Steuerung. Aus dieser will ich zyklisch Daten auslesen und in eine Cloud schreiben, sodass der Kunde immer einen relativ aktuellen Einblick bzw. Status seiner Anlage hat.
Mein C-Programm sendet über ein bestimmtes Hex-Kommando übers Netzwerk an die Steuerung. Dieser Hex-Code bedeutet für die Steuerung "lies Daten aus, beginnend ab der Speicheradresse bis zu einer weiteren Speicheradresse und sende mir die Daten zurück".
Die zurückkommenden Daten empfange ich an einem Socket und werden in einem Buffer gespeichert der wie folgt definiert ist (das hatte wir schon):unsigned char *buffer = (unsigned char *) malloc(65536);
Anschließsend wollte ich die ankommenden Daten als String haben um sie auseinanderzunehmen (hatten wir auch schon):
// Schreibt anz Bytes aus mem als Hexwerte in den Speicher ab text, der fuer len Zeichen Platz hat // Wenn der Platz nicht ausreicht, wird NULL zurueckgegeben, sonst text. char * hex2string(char *text, size_t len, void *mem, size_t anz) //ungetestet { unsigned char *m = mem; char *t = text; size_t i; for(i=0; i<anz; i++, m++) { if (text+len >= t+4) // " HExzoffer, ein Leerzeichen und die '\0' return NULL; t += sprintf(t, "%02x ", *m); } return text; }
Soweit der Stand.
Nun will ich mit sscanf den ganzen Hex-String auseinander nehmen.
Warum will ich das:
Ich habe ja aus der Steuerung auf einmal einen ganzen Speicherbereich augelesen, welcher diverse Daten beinhatet die Aussage geben über den aktuellen Status angeschlossener Komponenten.Also, mit sscanf nehm ich die ganze Hex-zeichenkette auseinander und weise den Wert diversen Variablen zu (char).
Die Variablen beinhalten nun einfach einen String mit einem Hex-Code.
Diese werden anschließend per Mail an die Cloud gesendet und dort verarbeitet.Wenn ich nun deine Funktion hex2String anwende und anschließend das ganze mit sscanf auseinander nehme und die Werte den entsprechenden variablen zuweise, funktioniert das nur einmal. Der Punkt ist das es die variablen dann bei der nächsten Abfrage nicht überschreibt. Die ganze Prozedur läuft in einer while-Schleife.
Das C-Programm läuft auf einem Raspberry Pi.
-
Der Umweg über die Hexdarstellung ist unnoetig.
Du kannst auf die Daten auch direkt zugreifen.
Und deinen problematischen Code hast du immer noch nicht gezeigt.