Hallo, wenn ich einen string habe, in den ich kontinuierlich reinschreibe, wie kann ich eine gewünschte Zeichenabfolge auch dann finden, wenn sie sich in den Randbereichen des strings befindet. Beispiel: Stringgröße: 10 Aktueller Inhalt: d e r 0 0 0 0 K i n Gesuchte Zeichenabfolge: Kinder Gruß Chris
Christian Stielz schrieb: > wenn sie sich > in den Randbereichen des strings befindet. einfach umrechnen if s[x] = 'K' && s[(x+1) % maxlen] = 'i' s[(x+2) % maxlen] = 'n' s[(x+3) % maxlen] = 'd' s[(x+4) % maxlen] = 'e' .... das was du unter string verstehst ist ein ringpuffer.
Ah- ok. "maxlen" kannte ich noch nicht. Werd mal googlen. ;) Gruß Chris
Christian Stielz schrieb: > "maxlen" kannte ich noch nicht. das gibt es auch nicht. Dort sollte der größe des Ringpuffers eingetragen weden. Entweder mit einem DEFINE oder mit sizeof()
Würde es für mein oben angegebenes Beispiel reichen, anstatt maxlen eine 10 einzutragen? Gruß Chris
Bei einem Ringpuffer musst Du die gleiche Strategie zum Lesen benutzen, wie die Schreibroutine. U.U. kann es nämlich sein, das sich, trotz anderer "Ansicht" die Zeichenkette: "Kinder" gar nicht im Puffer befindet. Zugegeben das Beispiel ist wohl an den Haaren herbei gezogen, aber es könnten auch das Ende von Wun"der" und der Anfang von "Kin"haken sein. Eine Interpretation ist ohne genaue Kenntnis von Anfang und Ende nicht möglich.
Christian Stielz schrieb: > Würde es für mein oben angegebenes Beispiel reichen, anstatt maxlen eine > 10 einzutragen? ja aber schön ist es halt nicht.
Argh- bekomme es nicht hin. :( if ((commandbuffer[i] = 'L') && (c[(commandbuffer+1) % 7] = 'i') (c[(commandbuffer+2) % 7] = 'b') (c[(commandbuffer+3) % 7] = 'e') (c[(commandbuffer+4) % 7] = 'l') (c[(commandbuffer+4) % 7] = 'l') (c[(commandbuffer+4) % 7] = 'e')) { Serial.println("Libelle gefunden"); i = 0; memset(commandbuffer,0,sizeof(commandbuffer)); }
Probiers mal so: if ((commandbuffer[i] == 'L') && (commandbuffer[(i+1) % 7] == 'i') && (commandbuffer[(i+2) % 7] == 'b') && (commandbuffer[(i+3) % 7] == 'e') && (commandbuffer[(i+4) % 7] == 'l') && (commandbuffer[(i+5) % 7] == 'l') && (commandbuffer[(i+6) % 7] == 'e')) { Serial.println("Libelle gefunden"); i = 0; memset(commandbuffer,0,sizeof(commandbuffer)); } = ist eine Zuweisung, == ein Vergleich --jmp
Hey, danke. Scheint aber noch immer nicht zu funktionieren, obwohl keine Fehlermeldung auftaucht. Hier mal der komplette Code: char commandbuffer[7]; char c; int i=0; void setup() { Serial.begin(9600); Serial3.begin(19200); Serial3.setTimeout(0); } void loop() { // <- An dieser Stelle steht mein kompletter restlicher Code, der auch noch verarbeitet werden muss. if (Serial3.available()) { c=Serial3.read(); commandbuffer[i] = c; i++; } /* if (strcmp(commandbuffer,"Libelle")==0) { Serial.println("Libelle gefunden"); i = 0; memset(commandbuffer,0,sizeof(commandbuffer)); }*/ if ((commandbuffer[i] == 'L') && (commandbuffer[(i+1) % 7] == 'i') && (commandbuffer[(i+2) % 7] == 'b') && (commandbuffer[(i+3) % 7] == 'e') && (commandbuffer[(i+4) % 7] == 'l') && (commandbuffer[(i+5) % 7] == 'l') && (commandbuffer[(i+6) % 7] == 'e')) { Serial.println("Libelle gefunden"); i = 0; memset(commandbuffer,0,sizeof(commandbuffer)); } }
Initialisiere mal oben commandbuffer direkt: char commandbuffer[7] = {"Libelle"}; und kommentiere das Einlesen des Zeichens vorübergehend aus. Was passiert dann?
Christian Stielz schrieb: //Schreib hier am Anfang mal #define MAXLEN 7 // damit machst du es Dir einfacher die Pufferlänge zu verändern. > > char commandbuffer[MAXLEN]; dann hier MAXLEN > > void loop() > { > > // <- An dieser Stelle steht mein kompletter restlicher Code, der auch > noch verarbeitet werden muss. > > if (Serial3.available()) > { > c=Serial3.read(); > commandbuffer[i] = c; > i++; Hier muß i = (i+1) % MAXLEN; sonst hast d upuggerüberlauf > } > /* if (strcmp(commandbuffer,"Libelle")==0) > { > Serial.println("Libelle gefunden"); > i = 0; > memset(commandbuffer,0,sizeof(commandbuffer)); > }*/ > if ((commandbuffer[i] == 'L') && > (commandbuffer[(i+1) % 7] == 'i') && > (commandbuffer[(i+2) % 7] == 'b') && > (commandbuffer[(i+3) % 7] == 'e') && > (commandbuffer[(i+4) % 7] == 'l') && > (commandbuffer[(i+5) % 7] == 'l') && > (commandbuffer[(i+6) % 7] == 'e')) die 7 immer durch MAXLEN ersetzten > (commandbuffer[(i+1) % MAXLEN] == 'i') && Du mußt eine eigenes i nehmen, also z.B. j da du ab i abragst ist maximal der erste Buchstabe da, der Rest ist noch gar nicht angekommen, oder rückwärtsabfragen, sprich bei i ist das 'e', bei i-1 das 'l' usw
>d upuggerüberlauf
=du Pufferüberlauf,
sry kan nnicht esitieren
@Christian Um himmels Wilhelm! Wann beschäftigst Du Dich endlich mal mit der Funktion des Ringpuffers? Wie ich oben, in meinem Post bereits angedeutet habe, wird das so, wie Ihr euch das Denkt, nichts. Was Ihr braucht: Anfang, Ende und Länge des Puffers, alles andere ist Zeitverschwendung. Werf' doch wenigstens eine halbe Pupille auf meinen Post. Natürlich musst Du nicht, irgendwann gereift vielleicht auch die Geht-So-Besser-Methode. Ob Du damit aber die mögliche(n) Doppeldeutigkeit(en) ausklammerst ist fraglich.
amateur schrieb: > Wann beschäftigst Du Dich endlich mal mit der Funktion des Ringpuffers? Sobald ich ein Tutorial gefunden habe, in dem dieser einleuchtend erklärt ist und nicht nur das suchen eines einzelnen Zeichens, sondern ganzer Zeichenketten innerhalb des Ringbuffers behandelt. Bisher bin ich leider nicht fündig geworden. Gruß Chris
Selbst hier in mikrocontroller.net sind mehrere Ansätze zu finden, insbesondere rund um die gepufferte serielle Schnittstelle. Die Wikipedia weiß es mit Sicherheit. Das Grundprinzip ist recht einfach: Es gibt zwei Zeiger. Der eine zeigt auf den Anfang - hier wird gelesen. Der andere zeigt auf das Ende - hierhin wird geschrieben. Sind beide gleich, so ist der Puffer leer. Wird gelesen, so wird der erste Zeiger erhöht. Wird geschrieben, so wird der zweite Zeiger erhöht. Erreicht einer der beiden Zeiger das Ende (max.), so wird er auf den Pufferanfang gesetzt. Liest Du mehr als drinnen ist (ohne Abfrage), so hast Du ein Problem - wie bei jedem leeren Puffer. Schreibst Du, trotzdem das Teil voll ist, so hast Du ebenfalls ein Problem - auch wie bei jedem vollen Puffer. Es gehören also ein paar Hilfsfunktionen (Voll/Leer) dazu – auch normal. Du hast jetzt zwei Möglichkeiten: 1. Du simulierst das Lesen nach den obigen Regeln ohne die eingebauten Zeiger zu verändern oder 2. Du liest brav alle vorhandenen Zeichen in einen eigenen Puffer und such dort.
Christian Stielz schrieb: > nicht nur das suchen eines einzelnen Zeichens, sondern > ganzer Zeichenketten innerhalb des Ringbuffers behandelt. Das ist schon missverstanden - der Ringbuffer ist nur im Speicher als Ring angeordnet, logisch ist er jedoch linear. Dazu braucht man eben einen Pointer auf den gerade gültigen Anfang, der logisch lineare String geht von da einmal um den Ring bis zum Zeichen vor dem Anfang. Da dir das Verständnis so extrem schwer fällt, machst du es wirklich am besten so, dass du den Inhalt ab dem Anfang in einen String üblicher Anordnung kopierst, auch wenn das zusätzlichen Speicherplatz kostet, dann kannst du vorhandene Vergleichsfunktionen verwenden oder abtippen. Gruss Reinhard
strncmp benutzen. An die Funktion den Pointer vom aktuellen Schreibzeiger übergeben. Die Länge ist die Differenz aus Schreibzeiger und aktuellen Lesezeiger. Oder Du vergleichst erst einmal ob das gerade geschriebene Zeichen dem Anfangszeichen des Suchstrings entspricht. Dann setzt Du dir ein Flag und rufst zyklisch strncmp auf. Arbeite Dich mal in Pointerarithmetik ein. Mit den []-Klammern wird das nix auf Dauer.
amateur schrieb: > Das Grundprinzip ist recht einfach: > Es gibt zwei Zeiger. > Der eine zeigt auf den Anfang - hier wird gelesen. > Der andere zeigt auf das Ende - hierhin wird geschrieben. Ok- Anfang= Position 0, Ende z.B. Position 8 amateur schrieb: > Sind beide gleich, so ist der Puffer leer. =? amateur schrieb: > Wird gelesen, so wird der erste Zeiger erhöht. Er geht also auf Position 1. Hm- da steht ja noch nix, weil nix reingeschrieben wurde= ? amateur schrieb: > Wird geschrieben, so wird der zweite Zeiger erhöht. Höher als 8 geht nicht, also springt er auf 0, oder? amateur schrieb: > Erreicht einer der beiden Zeiger das Ende (max.), so wird er auf den > Pufferanfang gesetzt. Das war doch eben der Fall=? amateur schrieb: > Liest Du mehr als drinnen ist (ohne Abfrage), so hast Du ein Problem - > wie bei jedem leeren Puffer. Das leuchtet mir ein. amateur schrieb: > Schreibst Du, trotzdem das Teil voll ist, so hast Du ebenfalls ein > Problem - auch wie bei jedem vollen Puffer. Auch klar. Bin noch immer auf der Suche nach einem gut erklärten Beispielringbuffer. Gruß Chris
amateur schrieb: > Selbst hier in mikrocontroller.net sind mehrere Ansätze zu finden, > insbesondere rund um die gepufferte serielle Schnittstelle. http://www.mikrocontroller.net/articles/FIFO#Standard-Ringpuffer
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.