Dekodieren binärer Daten

Winner

Erfahrenes Mitglied
Hallo zusammen.

Mein Problem, ich weis nicht wie ich es angehen soll. Zwar lese ich Binärdaten von einem Comprt ein. Ich weiß den Aufbau sowie die Länge der Message.

Jetzt lese ich jedes einzelne Zeichen ein und schreibe es in ein char Array. Dieses klappt für einige Message einwandfrei.

Nun das konkrete Problem. Sobald das eingelesen Zeichen eine binäre Null ( '\0') entspricht, macht er das Array zu. Wie kann ich das Umgehen. Kann mir einer Helfen Hier mal mein code der das einlesen übernimmt.

HTML:
INT i=0, n=0;
   CHAR ch;
   
   // Lese Laenge  --> Länge der Nachricht steht in Byte 2 ,3 ,4
   for ( i=2; i<5; i++)
   {
      ch = m_CComPort.ComGetch();
      if (m_CComPort.m_iComError != COM_OK) 
         return 0;
      s[i] = ch;                  
   }

   // Berechne Laenge, da diese in Hex Zahlensystem gelierfert wird
   n = CSNSBaseUtil::hexToInt(s[2])*256 + CSNSBaseUtil::hexToInt(s[3])*16 + CSNSBaseUtil::hexToInt(s[4]) ;   

   // Lese Body --> holen des Bodys der Nachricht
   for ( i=5; i<(n+5); i++) //n+5 da hier die ersten 5 Zeichen mit berechnet werden müssen
   {
      ch = m_CComPort.ComGetch();
      if (m_CComPort.m_iComError != COM_OK)
         return 0;
      s[i] = ch;  //und genau hier hackt es, sobald die binäre Null drin steht ist das Array               dicht
     
      if(ch=='\0'){
        CString str = "Binäre Null";
        AfxMessageBox(str);
      }
   }

Kann mir da einer weiterhelfen! Bitte Bitte
 
Sobald das eingelesen Zeichen eine binäre Null ( '\0') entspricht, macht er das Array zu.
Was verstehst du unter "zumachen"? Das Array kann exakt bis zu der Größe befüllt werden, für die Speicher reserviert wurde. Dabei ist es vollkommen egal, was für Zeichen dort hineingeschrieben werden.
BTW: Wo legst du eigentlich die Größe des Arrays fest? Hab dazu in deinem Code nichts entdeckt.

Die Null hat nur dann eine Bedeutung, wenn du den eingelesen Buffer als Text verarbeiten willst. Entsprechende Funktionen interpretieren das natürlich als Ende der Zeichenkette. Du solltest mal schreiben, welchen Zweck die eingelesenen Daten haben bzw. wie du diese verarbeiten willst. Davon hängt auch ab, ob und was du mit der Null machen sollst.

Gruß
MCoder
 
Vielen dankl schon mal für die Hilfe. Also sobald ich dann das ARRAY weiter verwenden möchte, sind es nur die Zeichen drin bis zu der binären NULL.

Mein Array wird so diefinert :
Code:
char  m_szReadData[ BUFSIZE ];
wobei Bufsize 4096 entspricht

Eigentlich möchte ich dieses nicht als Text verwenden. Nach dem einlesen der Daten möchte ich diese dann zu dekodieren weiter geben, Dazu übergebe ich das Array in eine Methode, die ein neuen Buffer anlegt, der den Body der Message nicht mehr enthält. Nach diesem umschreiben benutze ich das neue Array und kopiere es mit der memcpy Funktion in meine Struktur (die ich angelegt habe) für jede Message.
Also führe cih das ganze nochmal mit code auf. Hoffe das ich mich klar ausdrücken konnte.

Code:
//---------------------------------------------------------------------------------------------
INT CGNSSJavadReceiver::readBinaryData(CHAR *s)
//---------------------------------------------------------------------------------------------
{ //
   INT i=0, n=0;
   CHAR ch;
   
   // Lese Laenge  --> Länge der Nachricht steht in Byte 2 ,3 ,4
   for ( i=2; i<5; i++)
   {
      ch = m_CComPort.ComGetch();
      if (m_CComPort.m_iComError != COM_OK) 
         return 0;
      s[i] = ch;                  
   }

   // Berechne Laenge, da diese in Hex Zahlensystem gelierfert wird
   n = CSNSBaseUtil::hexToInt(s[2])*256 + CSNSBaseUtil::hexToInt(s[3])*16 + CSNSBaseUtil::hexToInt(s[4]) ;   

   // Lese Body --> holen des Bodys der Nachricht
   for ( i=5; i<(n+5); i++) //n+5 da hier die ersten 5 Zeichen mit berechnet werden müssen
   {
      ch = m_CComPort.ComGetch();
      if (m_CComPort.m_iComError != COM_OK)
         return 0;
      s[i] = ch;  
      
      
   }   
    
   return (i);
}


//Zwischenspeichern:
strcpy(m_Test,s);


//dann wird diese Funktion ausgeführt
/--------------------------------------------------------------
BOOL CGNSSJavadReceiverIMU::parseJavadAD(char *s, CGNSSJavadADMes *m_pJavadAD)
//--------------------------------------------------------------
{ SNS_TRY

 //bBuffer_AP=0;
    INT   nStrLens; //zum Überprüfen der Nachrichtenlänge
    INT   nStrLen;
    BOOL bCScorrect;
    int iMessageLength;
    

    //Plausibilitätsprüfungen der Message:
    //====================================

    //Die ersten 5 Zeichen enthalten den Identifeier und die Message Länge
    nStrLens = strlen(s); //ermittelt die Länges des Datenstromes
    
    //Vorab Prüfungen, ob die Message Plausibel sein kann oder nicht
    if (s == NULL || nStrLen < 5)
   {
      return FALSE; //Hier muss ich natürlcih ein BOOL Wert zurück liefern
   }

   //Checksumme des Datensatzes     
 /*  bCScorrect = CGNSSJavadReceiver::verifyChecksum(s);

    if(bCScorrect == 0)
    {
        return FALSE;
    }
   */ 
   // m_pJavadAD->empty();
    iMessageLength = nStrLen;
int     n = CSNSBaseUtil::hexToInt(s[2])*256 + CSNSBaseUtil::hexToInt(s[3])*16 + CSNSBaseUtil::hexToInt(s[4]) ;
iMessageLength=n;
    //in Char Buffer zwischenspeichern 

    char c_Buffer[BUFSIZE_AD_MES];
    int i;
    for(i = 5; i<(iMessageLength); i++)
    {
    
        c_Buffer[i-5] = s[i];
    }
    c_Buffer[i+1] = '\0'; 

    memcpy(&m_pJavadAD->structReceiverADMes,c_Buffer,strlen(c_Buffer)+1); //ich glaube hier liegt der Fehler Mcoder oder

    FILE *f_IMU_AD;
    f_IMU_AD = fopen("IMU_AD.txt","a");
    if(f_IMU_AD==NULL)
        fclose(f_IMU_AD);
    else{
      
        //fprintf(f_IMU_AD,"t = %u\trollgps = %f\trollins = %f\tpitchgps = %f\tpitchins = %f\theadgps = %f\theadins = %f\tvalid_flag = %u\tcs=%u\n",m_pJavadAD->structReceiverADMes.t,m_pJavadAD->structReceiverADMes.rollgps,m_pJavadAD->structReceiverADMes.rollins,m_pJavadAD->structReceiverADMes.pitchgps,m_pJavadAD->structReceiverADMes.pitchins,m_pJavadAD->structReceiverADMes.headgps,m_pJavadAD->structReceiverADMes.headins,m_pJavadAD->structReceiverADMes.valid_flag,m_pJavadAD->structReceiverADMes.cs);
      fprintf(f_IMU_AD,"t = %u\trollgps = %f\trollins = %f\tpitchgps = %f\tpitchins = %f\theadgps = %f\theadins = %f\tvalid_flag = %u\tcs=%u\n",m_pJavadAD->structReceiverADMes.t,
          m_pJavadAD->structReceiverADMes.rollgps,m_pJavadAD->structReceiverADMes.rollins,
          m_pJavadAD->structReceiverADMes.pitchgps,m_pJavadAD->structReceiverADMes.pitchins,
          m_pJavadAD->structReceiverADMes.headgps,m_pJavadAD->structReceiverADMes.headins,
          m_pJavadAD->structReceiverADMes.valid_flag,m_pJavadAD->structReceiverADMes.cs);
      fclose(f_IMU_AD);
    }

    return TRUE;

SNS_CATCH(101193)}

So ich hoffe es ist nicht so unüberischtlich.

Aber besten dank, winner

PS: Als Hintergrund, es sind Rohdaten die von einem GNSS System entgegengenommen werden müssen
 
Wenn du mit binären Daten arbeitest, kannst du keine String-Funktionen wie strlen(), strcpy() usw. verwenden, weil diese eben die Null als Textende erkennen und entsrechend reagieren. Du must die Anzahl der gelesenen Bytes als separate Vaeriable speichern und übergeben. Aus dem Buffer selbst kannst du die Länge nicht ermitteln.

Gruß
MCoder
 
Ok vielen dank für den Hinweis, ich werde das in meinem Code berücksichtigen! Aber sowas wie memcpy geht doch oder.

Dann würde ich es so aufbauen, dass ich den memcpy Befehl so verwende:


HTML:
memcpy(m_Test,m_szReadData,31);
wobei ich die 31 dann als variable verwenden werde.

Oder kann ich memcpy ach nicht verwenden und was ist die alternative dazu.

Vielen dank
 
hallo! Jetzthabe ich ein weiteres problem.

Zwar möchte ich beim schnellen loggen also mit 100Hz die Daten zwischen Buffern, da es ansonsten so lang dauert, diese in die Datei zu schreiben.

Kann mir da jetzt wer sagen wie ich stings die als binärdaten vorliegen zusammen fügen kann! Also mit memcpy komme ich da nicht allso weit, da ich immer wieder den vorderen teil überschreibe!

Wie geht das denn anders
 
Hallo,

mit memcpy() geht das schon. Du muss halt nur Einfügepostion immer entsprechend der bereits geschriebenen Bytes verschieben.
Hier mal das Prinzip:
C++:
char buffer[4096];

int nPosition = 0; // Einfügeposition

for( ... )
{
    char data[]    = { .... };  // Neue Daten
    int  nDataSize = ...        // Anzahl der neuen Bytes

    
    if( sizeof(buffer) < (nPosition + nDataSize) )
    {
        // Achtung Pufferüberlauf!
    }
    else
    {
        memcpy(buffer + nPosition, data, nDataSize);
        nPosition += nDataSize;
    }
}
Gruß
MCoder
 
Zurück