0x00 im Char-Feld handeln

sTEk

Erfahrenes Mitglied
Ich bins mal wieder...

...denn ich habe Probleme bei der Weiterverarbeitung meiner einzelnen char[65]-Felder, sobald ein Byte davon ein 0x00 ist. Dort bricht der Rechner die Verarbeitung der weiteren Zeichen ab - ist ja auch logisch. Dummerweise benötige ich aber immer diese exakt 64 Byte großen Stücken - und 0x00 ist bei insgesamt 256kB zu lesender Daten auch oft dabei.
Wie aber kann ich dem abhelfen?

Mein funktionierendes Programmstück hatte ich in diesem Tread bereits als Abschluss gepostet, der Übersicht halber schreib ich es aber noch mal rein:

Code:
	char    cominhalt[65]="\0";
  	CString temp(cominhalt);
  	int		m_bytes,i;
  
  	for (i=1; i<4100; i++)
  		{
  		port.Purge(PURGE_RXCLEAR);	//Den Lese-Puffer löschen
 		char comsender[11]="!n";	 // Das ist zur Kommunikation mit meinem
  	    port.Write(comsender,10);		    // µC notwendig
  		
  
  		m_bytes=port.Read(cominhalt,64);  //hier werden immer 64 Bytes eingelesen
  		m_EEPROM_Inhalt+=cominhalt;
  
  		m_status=m_EEPROM_Inhalt.GetLength();
  		
  		sprintf(buffer, "Page: %d", i);
  		sprintf(buffer1, "Länge: %i", m_bytes);
  		sprintf(buffer2, "%s", cominhalt);
  		SetDlgItemText(IDC_page,buffer2);
  		SetDlgItemText(IDC_bytes,buffer1);
  		SetDlgItemText(IDC_COM_Status,buffer);
  		UpdateWindow();
 	 Warte(3000);											 // Meine kleine Warte-Schleife, 
 																	 // damit ich sehe, was so passiert

Kann ich die eingelesenden Zeichen auch direkt in ihrem Hex-Code benutzen und handeln? Ich hatte bereits eine BYTE - Deklaration der Variable cominhalt probiert, allerdings mit gleichem Ergebnis. Sobald eine Hex-Null im 64Byte langen Eingelesenen ist wird er an der Stelle als abgeschlossen behandelt. :/
Die 64 Byte selbst liest er aber vollständig ein, das kann ich mittels m_bytes nachvollziehen.
 
Zuletzt bearbeitet:
Hallo,
bastle dir doch eine Funktion zum Entfernen des '\0' selber...
Ungefähr so:

Code:
#include <iostream>

using namespace std;

void strip(char* dest, char* src, int length){

        for(int i = 0; i < length; i++){ 
                if(src[i])
                        strncat(dest, &src[i], 1);
        }
}
                     
int main(){

        const int MAX_STRING_LENGTH = 64;

        char test[MAX_STRING_LENGTH] = "This\0 is\0 only\0 for\0 test purposes";
        cout << test << endl;
        char result1[MAX_STRING_LENGTH] = "\0";

        strip(result1, test, MAX_STRING_LENGTH);
        cout << result1 << endl;

        return 0;
}

Gruß

RedWing
 
Ich möchte die "\0" ja nicht raus haben - ich brauche sie ja, denn es sind genauso Controllerdaten.
Ich müsste die irgendwie als ganz normales Byte behandeln.
Am liebsten ist es mir, wenn alle eingelesenen Zeichen als normale Bytes behandelt werden können. Aber dann kann ich die nicht in ein CString schieben, oder?

Sollte ich dann lieber jedes Zeichen extra einlesen und in ein entsprechend großes Feld schieben?
Wie aber behandle ich dort die Zeichen in ihrer eigentlichen Hex- oder Binär-Form?
 
Aber dann kann ich die nicht in ein CString schieben, oder?

Können tust dus schon aber du kannst dann die Funktionen sämtlicher Stringbibliotheken
nicht verwenden da sie Strings alle mit '\0' als abgeschlossene Strings sehen....

Sollte ich dann lieber jedes Zeichen extra einlesen und in ein entsprechend großes Feld schieben?

Ist jedes einzelne Controllerdatum(Befehl?) mit einem '\0' abgeschlossen?

In welcher Art willst du die Daten denn weiterverarbeiten, bevor sie zum Controller geschickt
werden können?

SetDlgItemText(IDC_bytes,buffer1);

Wenn du den Inhalt eines solchen 64 stelligen Strings auf dem Computerr ausgeben willst
wirst du wohl nicht drumrum kommen die \0 zu entfernen..

Gruß

RedWing
 
Die Daten, die ich lese, sind der Speicherinhalt des externen ROMs meines µC. Er umfasst insgesamt 256kB. Zur besseren Verarbeitung lese ich diesen ROM mit dem µC in 64-Byte-Scheiben ein und nutze diese Funktion auch, um diese Scheiben an den PC zu senden. Hier möchte ich natürlich schon den gesamten ROM-Inhalt in einem Stück haben, denn die Informationen darin sind so aufgebaut, dass ich alles zusammen benötige (vorderer Teil ein Header mit Pointern auf ROM-Bereiche, hinterer Teil die eigentlichen Daten)
Den Inhalt des ROMs möchte ich nun auswerten, modifizieren und wieder senden. Dazu muss ich im Ernstfall jedes Byte anfassen. Da liegt der Hund begraben...ich muss also alles binär oder wenigstens in Hexform handhaben, denn es ist von 0x00 bis 0xff alles drin.

Ich habe gerade mal die Einzeleinlesung getestet (mit BYTE cominhalt[1]; ), leider sagt er mir, dass bei einer 0x00 o Bytes gelesen worden sind...komisch, wenn er doch den Befehl ausführt und auch das richtige Zeichen liest (er wartet sonst Ewigkeiten, bis gewünschte Anzahl zu lesender Bytes im Eingangspuffer ist)
Ich habe ein Programm namens Docklight Scripting, das zeigt mir wahlweise in Hex, ASCII, DEc an - also muss es doch irgendwie machbar sein, oder?
 
Zuletzt bearbeitet:
Ich habe gerade mal die Einzeleinlesung getestet (mit BYTE cominhalt[1]; ), leider sagt er mir, dass bei einer 0x00 o Bytes gelesen worden sind...komisch, wenn er doch den Befehl ausführt und auch das richtige Zeichen liest (er wartet sonst Ewigkeiten, bis gewünschte Anzahl zu lesender Bytes im Eingangspuffer ist)

Wenn er das read beiom einlesen einer 0x00 ausführt dann lass dir doch mal das
Zeichen was angeblich eingelesen wurde als Integer auf dem Bildschirm ausgeben,
wenn da ne null drin steht passt es ja...

Ich habe ein Programm namens Docklight Scripting, das zeigt mir wahlweise in Hex, ASCII, DEc an - also muss es doch irgendwie machbar sein, oder?
Mir ist immer noch nicht so richtig klar was eigentlich machbar sein soll?
Du kannst wie schon gesagt die Zahlen als Zahlen bearbeiten, aber sämtliches
Bearbeiten mit Stringfunktionen würde in deinem Fall entfallen.

Eine Überlegung wäre vielleicht die Daten nicht in einen char[] einzulesen sondern gleich
in eine Struktur damit die Bearbeitung überischtlicher wird:
Die Struktur könntest du so aufbauen wie dein Protokoll von deinem Controller
gestaltet ist:
Code:
struct Header{
  int cmd;
  ...
  int data[1024];
};

Dafür musst du das Headerfornmat deines Controllers aber genau kennen.
Und die Wahl der Typen in deiner Struct wie int usw so wählen das sie mit den im Header
angegebenen bytes übereinstimmen (char = 1 byte int = 4 bytes usw)...
Ich hoffe ich konnte dir helfen...

Gruß

RedWing
 
Zuletzt bearbeitet:
Habe mir gerade mal die eingelesenen Zeichen als Integer anzeigen lassen, dummerweise ist das immer eine 1241292, also nicht richtig.
Wenn ich sie als String anzeigen lasse (%s) dann stimmts jedoch (solange keine 0x00)

Dass ich alles als Zahl bearbeiten muss hab ich verstanden, abere wie als Zahl einlesen? Dass macht mir Kopfschmerzen.


Danke!
 
Habe mir gerade mal die eingelesenen Zeichen als Integer anzeigen lassen, dummerweise ist das immer eine 1241292, also nicht richtig.
Hast du dir die Anfangsaddresse von cominhalt anzeigen lassen oder den entsprechenden
Inhalt?:

Code:
m_bytes=port.Read(cominhalt,1);
cout << (int)cominhalt[0] << endl;

Dass ich alles als Zahl bearbeiten muss hab ich verstanden, abere wie als Zahl einlesen? Dass macht mir Kopfschmerzen.

Definiere dir eine Struktur die den Header deines Controllers abbildet:

Code:
struct Header{
  int cmd;
  ...
  int data[1024];
};

RedWing hat gesagt.:
Dafür musst du das Headerfornmat deines Controllers aber genau kennen.
Und die Wahl der Typen in deiner Struct wie int usw so wählen das sie mit den im Header
angegebenen bytes übereinstimmen (char = 1 byte int = 4 bytes usw)...

Besorge dir ein Objekt für die Struktur:

Code:
Header* data = new Header;

Lese die Daten über read ein indem du den Zeiger auf Header einfach in einen char*
umcastest damit er mit deiner read Funktion konform ist:

Code:
m_bytes=port.Read((char*)data,sizeof(Header));

So sollte es gehen, danach sollten die Daten in deiner Struktur zugänglich sein,
wenn du sie richtig abgebildet hast...

Gruß

RedWing
 
Zuletzt bearbeitet:
Danke Dir, werd ich morgen gleich ausprobieren.

Bei der 0x00 hab ich mitbekommen, dass die read-Funktion nichts einliest, sie denkt wohl, dass 0x00 kein neuer Inhalt vom Eingangspuffer ist. Aber irgendwie muss es ja gehen, andere Programme schaffen es ja auch, eine 0x00 einzulesen.
 
Bei der 0x00 hab ich mitbekommen, dass die read-Funktion nichts einliest, sie denkt wohl, dass 0x00 kein neuer Inhalt vom Eingangspuffer ist. Aber irgendwie muss es ja gehen, andere Programme schaffen es ja auch, eine 0x00 einzulesen.

Ich kenne diese Funktion zwar nicht, aber ich habe im Thread schon mitbekommen das sie
wohl Annahmsweise ein Lese Interface zur seriellen Schnittstelle für die Windoof API bietet. Und
von daher kann ich mir nicht vorstellen das sie eine 0 einfach so überliest, da es ja auch ein
Datum ist was über die serielle Schnittstelle geschickt werden kann.
Schau dir nochmal deine Debug Ausgabe an...

Gruß

RedWing
 
Zurück