Beschnittene Zeichenabfolge in string gesucht

OP #3289843
Lesenswert?
• ▲
▼
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
Gast #3289885
Lesenswert?
• ▲
▼
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.
OP #3289889
Lesenswert?
• ▲
▼
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));
   }
Gast #3289996
Lesenswert?
• ▲
▼
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
OP #3290033
Lesenswert?
• ▲
▼
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));
   }
}
Gast #3290121
Lesenswert?
• ▲
▼
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
Gast #3290128
Lesenswert?
• ▲
▼
@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.
Gast #3290239
Lesenswert?
• ▲
▼
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.
Gast #3290689
Lesenswert?
• ▲
▼
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
Gast #3290713
Lesenswert?
• ▲
▼
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.
OP #3291321
Lesenswert?
• ▲
▼
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

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