UART, String, Array, einzelne Zeichen extrahieren

OP #973796
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
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
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
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.
Gast #973943
habe jetzt nur flüchtig hingeschaut und weiss auch nicht um welchen 
Compiler es geht, aber meiner Meinung nach fehlt bei den 
Zeigerzuweisungen der Adressoperator.

Bsp.
status = &temp[0];
OP #973955
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
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
@ 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
>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

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.