UART, String, Array, einzelne Zeichen extrahieren

OP #973796
Lesenswert?

Hallo liebes Forum!

Ich hab ein kleines Problem beim Zerstückeln eines Strings den ich über 
die UART empfangen hab. Der String steht in dem Array buf drinn. An ganz 
bestimmten Stellen dieses Arrays stehen Informationen die ich brauche. 
Die stehen auch immer genau da, weil es so vom Protokoll vorgegeben ist. 
Zum Beispiel will ich die beiden Zeichen buf[10] und buf[11] 
hintereinander in einen String Pointer schreiben. Den Pointer brauche 
ich damit ich damit dann eine Suchanfrage in einer SQL Datenbank starten 
kann.

Kleiner Codeauszug:
1
char buf[255];
2
char *status;
3
char temp[10];
4

5
/* lese aus UART in buf ein, mache malloc für status */
6

7
temp[0] = buf[10];
8
temp[1] = buf[11];
9
temp[2] = '\0';
10
status = (char *)temp;
An dieser Stelle bricht das Programm dann mit einem segmentation fault 
ab.

Hat einer eine Idee was ich falsch mache oder wie es eleganter 
funktioniert?

Hab selbst schon mit sprintf() und mit strncat() es versucht. Aber bei 
beidem ein seg. fault.

Gruß Björn Niethammer
Gast #973816
Lesenswert?

Sicher das der "segmentation fault" bei diesem Code Schnipsel auftritt, 
denn so verkehrt sieht das ganze nicht aus. Es sind alles einfache 
Zuweisungen da kann so etwas nicht passieren.

Was soll der Kommentar sagen "mache malloc für status " ich sehe im dem 
Code kein malloc.


Eventuell mal etwas mehr Code schicken.
OP #973846
Lesenswert?

Hallo Peter!

Danke für deine Antwort. Ich fand meine Code eigentlich auch nicht so 
schlecht. Aber anscheind ist da ja doch noch ein gravierender Fehler 
drinn. Bin mir eigentlich super sicher das bei den Codezeilen der Fehler 
auftaucht. Denn wenn ich es weglasse funktioniert mein Programm.

Hab mal einen etwas ausführlicheren Code angehängt. Mit UART 
Initialisierung und einlesen und allem drum und dran. Die Sachen für den 
Datenbank Zugriff hab ich gelöscht denn das funktioniert auch soweit 
alles.

Zum Verständnis: Es wird etwas über UART empfangen und dann anhand des 
Zeichen an der Stelle 9 im Buffer ausgewählt was zu tun ist. Nachdem das 
vollzogen ist und der Fall das dort das Zeichen '6' drinn steht soll 
weiter geschaut werden was für Zeichen an den anderen Positionen stehen. 
Damit muss dann später eine SQL Anweisung zusammengebastelt werden a la: 
"UPDATE TABLE WHERE STATUS_ID = <Wert von status>;" Deswegen der ganze 
Aufwand.

Gruß Björn
Angehängte Dateien:
Gast #973872
Lesenswert?

Ich habe jetzt nicht alles angeschaut, aber der Fehler liegt wol hier:

temp[0] = (char)buf[10];
temp[1] = (char)buf[11];
temp[2] = '\0';
status = temp;

temp[0] = (char)buf[16];
temp[1] = (char)buf[17],
temp[2] = '\0';
zentr_nr = temp;

temp[0] = (char)buf[20];
temp[1] = (char)buf[21];
temp[2] = (char)buf[22];
temp[3] = (char)buf[23];
temp[4] = '\0';
linien_nr = temp;

temp[0] = (char)buf[24];
temp[1] = (char)buf[25];
temp[2] = '\0';
melder_nr = temp;


die Variablen status, zentr_nr, linien_nr, melder_nr sind alles Zeiger 
und habe selber keinen Inhalt - sie Zeigen nur auf das Array temp. Damit 
Zeigen alle auf die selben daten.
Der SegmentFault wird wohl kommen weil die Variablen nicht den Inhalt 
haben den du willst.
OP #973955
Lesenswert?

Danke Peter. Ich hatte dann auch gedacht dass es mit einem 
Adressoperator geht. Aber dann bleibt es trotzdem der gleiche Inhalt auf 
den die Zeiger zeigen. Hab mich deswegen von den Zeigern getrennt und 
dafür auch Arrays deklariert und nun funktioniert es.

Als Compiler wird übrigens ein GCC Derivat der als ARM Cross Compiler 
installiert ist genutzt.

Vielen Dank für deine Mühe.

Gruß Björn
Gast #973963
Lesenswert?

Du hast stehen:
1
status = (char *)temp;

Das müsste aus dem Wert in Temp (ich weiß nicht genau, als was er das 
interpretiert, als u8 oder u16) eine Adresse machen.
Also steht vorher der u16-Wert zB 40000 drin, steht nachher im Pointer 
status auch der Wert 40000.
Das ist als Adresse natürlich unsinn.

Es sollte wohl so:
1
status = &temp;

Oder vielleicht so sein:
1
status = (uint8_t*)  (uint16_t)buf[10]   |  ( (uint16_t)buf[11] << 8);
#974126
Lesenswert?

@ Peter:
@ Matthias Lipinsky:

temp ist ein char-Array, damit ist
temp
(char*)temp
&temp
&temp[0]
hier alles äquivalent.

> Oder vielleicht so sein:
>
1
> status = (uint8_t*)  (uint16_t)buf[10]   |  ( (uint16_t)buf[11] << 8);
2
>

Und das ist doch gänzlich unsinnig. Nicht nur, dass da eine Klammerung 
fehlt, du glaubst doch nicht wirklich, dass beim OP ein Pointer per UART 
übertragen wird, der dann beim Empfänger irgendwo in den Speicher zeigt, 
oder?
Gast #974172
Lesenswert?

>dass beim OP ein Pointer per UART
>übertragen wird, der dann beim Empfänger irgendwo in den Speicher zeigt,
>oder?

Nein. Stimmt. Wenn dann wird ein Arrayindex übertragen.
Ich ziehe den Post zurück

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren