Parsen



  • Ja schon, aber wie bekomme ich da die Attribute aus dem Mittelteil der zeichenkette heraus. Damit kann ich ja nur das erste Attribut herausholen. Danach müsste ich ja die Zeichenkette verkürzen vom Anfang her.

    Was vlt noch mögich ist:
    Mit strlen die Länge ermitteln und anschließend mit ner for Schleife jedes Zeichen einzeln auswerten mittels if Abfragen anhand der Position....ist aber unvorteilhaft bei Zeichenketten mit einer Länge von 300 Aufwärts...

    Gruß


  • Mod

    tooony schrieb:

    Ja schon, aber wie bekomme ich da die Attribute aus dem Mittelteil der zeichenkette heraus. Damit kann ich ja nur das erste Attribut herausholen. Danach müsste ich ja die Zeichenkette verkürzen vom Anfang her.

    const char *foo="Hallo du da";
    strncpy(irgendwohin, foo + 6, 2); // "du"
    


  • Wenn das Format bekannt ist, nimm doch sscanf() .

    Um bei Deinem Beispiel zu bleiben:

    char att1[2], att2[4], att3[4];
      sscanf(data, "%2c%4c%4c", att1, att2, att3);
    


  • Gute Idee! Danke, ihr habt mir echt weitergeholfen 🙂



  • Ich nochmal:

    so ganz haut das noch nicht hin...

    Über ein Socket speichere ich die ankommenden Hex Zeichen in einem buffer:

    unsigned char *buffer = (unsigned char *) malloc(65536);
    

    Das ganze Auszugeben als Hex und als normalen Text ist mittels for-Schleife nicht das Problem, aber das auseinandernehmen wie in den Post zuvor beschrieben funktioniert noch nicht so wirklich.

    wenn ich z.B. die ersten 28 Zeichen auslese mit einer eurer Methoden:

    char fins_response[500];
    strncpy(fins_response, buffer,28);
    printf("%s\n", fins_response);
    

    wird nix ausgegeben bzw. nur ein "Sonderzeichen".

    Bei der Lösung mit sscanf das gleiche Spiel.

    Ziel ist es einfach die ankommende Zeichenkette zu zerlegen und jeden einzelnen Teil in einem char zu haben.



  • Lassen sich die 28 Byte denn als string ausgeben? Ich meine ergibt das Sinn oder sind das u.U. alle moeglichen Werte? Insbesondere auch '\0' - Dann ist fuer strncpy() eh schon alles zu spaet...

    Und wie ist es mit dem terminierenden Nullbyte? Ist das sicher da?
    Ansonsten musst Du z.B. bei printf() eine precision mit angeben.

    char fins_response[500];
    strncpy(fins_response, buffer,28);
    printf("%.28s\n", fins_response);
    


  • Um was für Zeichen/Werte handelt es sich denn?

    In deinem ersten Post hast du von char und Zeichenkette geschrieben. Das hört sich nach Klartext an. (Zeichen die bei isgraph wahr ergeben)

    Jetzt hast du unsigned char.

    Was kommt da an?
    Was ist bei printf("%s\n", buffer);

    Bei Sockets kann die Übertragung in mehreren Stücken erfolgen.
    Du musst dann selber sehen ob alle Daten angekommen sind.



  • 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):

    www.main.tooony.de/screen.jpg

    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 das int - oder short -Werte oder stehen die unsigned 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);
    

Anmelden zum Antworten