Hallo, ich möchte gerne ein Teil eines über den UART empfangenen Strings vergleichen. Ändert sich der Teilstring, so soll ein Counter erhöht werden. sprich ich will den ersten empfangenen String mit compare_string vgl. wenn beide ungleich sind, soll der Counter erhöht werden. Allerdings sende ich immer alle von alarm_data empfangenen Teilstrings...Wäre dankbar, wenn mir hierbei jemand weiterhelfen könnte. Grüße
Leider schreibst Du nicht, was nun eigentlich das Problem ist. Du formulierst auch leider etwas ungeschickt. Zum einen ist mit: >Ändert sich der Teilstring ... nicht klar, ob Du zwei zeitlich hintereinander eingehende Strings meinst oder zwei Teilstrings die zusammen hereingekommen sind. Nach erstem Überfliegen Deines Codes meinte ich, dass das letztere zutrifft. und in >Allerdings sende ich immer alle von alarm_data empfangenen >Teilstrings wird der Variable alarm_data eine Aktivität (das empfangen) zugeschrieben, was sinnlos ist, denn eine Variable führt nichts aus und Du sprichst davon das "Du" etwas tust anstelle des Rechners. Diese drei Punkte sind für sich genommen schon irgendwie pragmatisch deutbar, eher ungeschickt, bedeuten aber eine Unsicherheit die sich durch die Anzahl so akkumuliert, dass der ganze Text als Darstellung zweifelhaft wird. Wie gesagt: Der Hauptpunkt ist, das das Problem nicht genannt ist. Auffällig ist aber, dass compare_data keine Daten enthält, wenn Du strcmp aufrufst, denn die Variable wird auf dem Stack angelegt, so das höchstens irgendwelche zufälligen Daten dort stehen, aber nichts "bestimmtes". Evtl. hast Du hier ein static vergessen. Der Code der Daten in compare_data umkopiert muss natürlich auch mindestens einmal ausserhalb der Funktion vorhanden sein. Noch ein kleiner Verbesserungstip: Die Schleifen zum umkopieren könntest Du durch strncmp ersetzen. Mehr fällt mir nicht auf.
Hallo Guru, sorry, du hast Recht, dass ist wirklich blöd formuliert. Also im Grunde möchte ich den empfangenen Teilstring(alarm_data) mit dem vorherigen, in compare_data abgelegten, String vergleichen. Unterscheidet sich der neue String vom alten (in compare_data abgelegt), so soll der counter erhöht werden und der neue String in compare abgelegt werden. Im Grunde immer ein Vgl. mit dem vorherigen String. Allerdings macht das mein Programm nicht und sendet einfach nur die aktuellen Strings alarm_data. Gruß
Aha. Ich hab Dir ja Tips gegeben. Schau sie Dir mal an. Es gibt zwei Punkte die Du beachten musst: 1. Was macht das Programm wenn zuvor noch garnichts empfangen wurde? Z.B. unmittelbar nach einem Reset. Du musst die Variable, die den vorher empfangenen String speichert passend initialisieren. Z.B. mit '\0'. 2. Wie sorgst Du dafür, das der vorher empfangene String gespeichert bleibt? Hier entweder static oder globale Variable.
>Allerdings macht das mein Programm nicht und sendet einfach nur die >aktuellen Strings alarm_data. Das könnte auch problemunangemessen formuliert sein. Nach dem Code ist es ja gerade Absicht, das der aktuelle String in alarm_data gesendet wird. Ich vermute aber das Problem ist, das der String "jedesmal" gesendet wird, als wenn er "jedesmal" unterschiedlich ist. Das hängt mit dem obigen Tip zusammen, das die Variable ihren Inhalt nicht hält wenn die Funktion verlassen wird. Also fehlt static bzw. die Deklaration im globalen Namensraum.
Hallo Guru, zunächst einmal vielen Dank für deine Tipps. >Der Code der Daten in >compare_data umkopiert muss natürlich auch mindestens einmal ausserhalb >der Funktion vorhanden sein. Das versteh ich nicht ganz. Weshalb? stringbuffer ist ja ne globale Variable, von der ich die Daten in alarm_data kopiere. wenn ein kompletter String empfangen wurde, wird system_data == 1 und ich springe in die Funktion. Gut, compare_data habe ich nun mal static gemacht und mit '\0' initialisiert. Allerdings klappt es immer noch nicht. Hmmmmm, zum Haare raufen...
> if(system_data == 1) Wenn system_data in einer ISR (UART RX?) gesetzt wird, muss es bei der Definition volatile gekennzeichnet sein. > // 10 Zeichen aus globalem Puffer stringbuffer > // in lokalen Puffer alarm_data kopieren > j = 0; > for( i = 32; i< 42; i++) > { > alarm_data[j] = stringbuffer[i]; > j++; > } > alarm_data[j] = '\0'; // <== #1 Zeile #1 zerstört dir das 10. Zeichen im lokalen Puffer! > char alarm_data[10]; > char compare_data[10]; > ... > if( strcmp(alarm_data,compare_data) != 0 ) compare_data[] ist nie initialisiert. Der Stringvergleich damit ist witzlos. Wenn du immer mit dem vorherigen Aufruf der Funktion vergleichen willst, benutze eine statische Variable und u.U. einen Defaultwert fürs leichtere Debuggen > static char compare_data[10] = "LEER";
>Allerdings klappt es immer noch nicht. Hmmmmm, zum Haare raufen...
Bitte analysiere einmal selbst das Problem. Schau' Dir genau an was
geschieht. Nimm den Simulator, baue Debug-Ausgaben ein. Lies die
Funktionsbeschreibungen, lies ein C-Buch.
Ich habe Dich schon in die richtige Richtung gedreht, aber nun möchte
ich, dass Du alleine läufst.
Noch ein kleiner abschliessender Tip:
Schau Dir genau an, wie der Vergleich beim ersten und bei den folgenden
Malen abläuft, was verglichen wird und was das Ergebnis ist.
So. Ich halte mich dann mal raus.
> if( strcmp(alarm_data,compare_data) != 0 )
Kann schief gehen, wenn in stringbuffer Nullbytes enthalten sind. Die
for-Schleife kopiert 10 Bytes ohne Rücksicht auf Nullbytes. Aber die
strcmp()-Funktion beendet beim ersten Nullbyte in einem der beiden
Puffer den Vergleich.
Hallo, ich habs hin bekommen und es läuft sowit auch ganz gut. eine Verständnisfrage habe ich allerdings noch und ich würde mich freuen, wenn mir diesbezüglich jemand weiterhelfen könnte. Wenn ich folgendes ausführe, lade ich ja zunächst meine Daten in alarm_data (char alarm_data[15])... j = 0; for( i = 32; i < 42; i++) { alarm_data[j] = stringbuffer[i]; j++; } j++; alarm_data[j] = '\0'; ...und erhöhe mein Puffer dann nochmal um eins, um '\0' reinzuschreiben. So klappt das auch mit dem strcmp perfekt. Nur wenn ich jetzt diese Variante wähle, klappt es nicht. Nach durchlaufen der for-Schleife, ist j=10. Es muss so ja auch funktionieren indem ich das zusätzliche Zeichen aus dem stringbuffer einfach mit '\0' überschreibe. Allerdings klappt es nicht so richtig. j = 0; for( i = 32; i <= 42; i++) { alarm_data[j] = stringbuffer[i]; j++; } alarm_data[j] = '\0'; Welchen Denkfehler mach ich da, ich komm nicht drauf
>> char alarm_data[10]; > for( i = 32; i <= 42; i++) > { > alarm_data[j] = stringbuffer[i]; > j++; > } > alarm_data[j] = '\0'; i j ====== 32 0 33 1 34 2 35 3 36 4 37 5 38 6 39 7 40 8 41 9 42 10 alarm_data[j ist 10] = '\0'; 1. Bufferoverflow -- for wird verlassen alarm_data[j ist 10] = '\0'; 2. Bufferoverflow
Mist, Copy&Paste Error 42 10 alarm_data[j ist 10] = stringbuffer[i ist 42]; 1. Bufferoverflow
Hallo Serieller, ich hab aber char alarm_data[15]! >Wenn ich folgendes ausführe, lade ich ja zunächst meine Daten in >alarm_data (char alarm_data[15])...
Und nach der for-Schleife ist j 11, also alarm_data[j ist 11] = '\0'; 2. Bufferoverflow
> ich hab aber char alarm_data[15]! Wusste ich nicht. In den bisherigen Fragen tauchte immmer ein Array mit Größe 10 auf. >Wenn ich folgendes ausführe, lade ich ja zunächst meine Daten in >alarm_data (char alarm_data[15])... Dieses Codestück habe ich in deinen Fragen noch nie gesehen.
sorry,
nach deinem Post vom
>Datum: 16.03.2011 14:04
habe ich das abgeändert. Deswegen bin ich jetzt auch so verwirrt, das es
nicht klappt.
Der Code oben in Variante 2 kopiert 11 Zeichen aus stringbuffer ab Position 32 bis einschliesslich 42 nach alarm_data und schliesst alarm_data mit einem Nullbyte ab. Deine These "Es muss so ja auch funktionieren indem ich das zusätzliche Zeichen aus dem stringbuffer einfach mit '\0' überschreibe." ist falsch. Das Nullbyte wird in obigem Code angehängt und überschreibt nicht.
Aha, ok. Sprich, bei einem Buffer alarm_data[15]... >j = 0; >for( i = 32; i < 42; i++) >{ > alarm_data[j] = stringbuffer[i]; > j++; >} > j++ > alarm_data[j] = '\0'; ... müsste ich nicht noch zusätzlich > j++ > alarm_data[j] = '\0'; ausführen/schreiben, da das automatisch gemacht wird...VG und vielen Dank für deine Antworten
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.