byte array Patternsuche , bzw. wie übergebe ich ein ByteArray an eine Funktion?

Hi,

heute brauche ich mal wieder eure Hilfe.
Steh voll aufm Schlauch.
Habe ein byte array. Das wird über die serielle Schnittstelle gefüllt. Anschliessend will ich in dem array nach einer definierten Bytefolge suchen, und die Position zurück bekommen.
Da ich hier keine fertige Funktion (so wie strstr() für charrArrays) kenne, wollte ich es zu Fuß machen.
Aber irgendwie scheitere ich schon an der Übergabe an meine Funktion.
Hier mal der entsprechende Code. Abgespeckt auf ein 1Byte-Pattern

byte SerIn[300];  //Eingangspuffer serielle Schnittstelle
// Array wird über die serielle Schnittstelle gefüllt

   byte SearchStr[] = {0xFF};
   int ziel =  Search (SerIn, SearchStr); 
   UdpDebug << "Zeiger auf Ergebnis:  " << ziel  << endl;


//--------------------------------------------
int Search(byte src[], byte pattern[])
{
    int c = sizeof(src) - sizeof(pattern) + 1;
    for (int i = 0; i < c; i++)
    {
        if (src[i] == pattern[0]){
     return i;
        }
    }
    return -1;
}
//--------------------------------------------

Bin um jeden Tip dankbar,

Gruß/hk007, oder

Hi

Versuch Mal Folgendes;
int Search(byte* src, byte* pattern)

Du übergibst die Adressen der Arrays, Das müsste mit byte* (Zeiger auf Byte) klappen.

MfG

postmaster-ino:
Versuch Mal Folgendes;
int Search(byte* src, byte* pattern)

Hi, danke für den Tip.
klappt aber iwie wieder nicht.
Bekomme immer wieder -1 zurück, obwohl das Muster definitiv im Array SerIn drin ist.
Glaube, dass die Übergabe nicht funktioniert, da ich für sizeof(src) und auch für sizeof(pattern) den Wert 4 bekomme.

BTW: Das hätte ich auch schon probiert:

int Search(byte *src, byte *pattern)

Hi

Ein Zeiger beansprucht den Platz von 4 Byte - somit hast Du also einen Zeiger übergeben - lag ich schon Mal nicht ganz falsch :).

Ok, dann tausche das * gegen ein &, mit etwas Glück übergibst Du damit eine Referenz - wenn Ja, arbeitet die Funktion mit den Original-Daten - also Änderungen an Diesen ändern die Daten auch außerhalb.

Wenns denn klappt (oder auch nicht) - bin ich aber raus, da ich keine Ahnung habe, was dann Da wirklich abläuft :wink:

MfG

int Search(byte *src, byte *pattern)

Bei der Zeigerübergabe geht die Länge des Arrays verloren.

Ein darauf folgendes sizeof(src) oder sizeof(pattern) wird jeweils die Größe des Zeigers liefern.

postmaster-ino:
Ok, dann tausche das * gegen ein &, mit etwas Glück übergibst Du damit eine Referenz - wenn Ja, arbeitet die Funktion mit den Original-Daten - also Änderungen an Diesen ändern die Daten auch außerhalb.

Nix besser ;-(

Bei der Zeigerübergabe geht die Länge des Arrays verloren.

Aha, das ist wohl des Pudels Kern....
Hab jetzt mal einen festen Wert für die Länge rein geschrieben. Sieht schon besser aus :slight_smile:

Futter für die Wühlkiste:

template<typename HaystackType, typename NeedleType, size_t HaystackSize, size_t NeedleSize> int search(HaystackType (&haystack)[HaystackSize], NeedleType (&needle)[NeedleSize])
{
    int c = HaystackSize - NeedleSize + 1;
    for (int i = 0; i < c; i++)
    {
        if (haystack[i] == needle[0])  return i;
    }
    return -1;
}

void setup() 
{
  Serial.begin(9600);
  Serial.println("Start");


  byte haystack[] {3,7,4,3,8,9};
  byte needle[]   {7};
  Serial.println(search(haystack,needle));
}

void loop() 
{
}

Bezeichner klarifiziert

combie:

template<typename A, typename B, size_t Acount, size_t Bcount> int search(A (&haystack)[Acount], B (&needle)[Bcount])

Also das mit dem template und so weiter kapier ich beim besten Willen nicht.

Ich hätte jetzt einfach die beiden Array-Längen noch mit übergeben.
So ist mein aktueller Code.
Erweitert um variable Patterngröße

...
    byte SearchStr[] = {0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF};
    int ziel =  Search (SerIn, SearchStr, sizeof(SerIn), sizeof(SearchStr));  
    UdpDebug << "Pointer auf Ergebnis: " << ziel << endl;
...

int Search(byte* src, byte* pattern, int SizeSrc, int SizeSearchStr)
{
    int c =  SizeSrc - SizeSearchStr + 1;
    int j;
    for (int i = 0; i < c; i++)
    {
        if (src[i] == pattern[0])
        {
           for (j = SizeSearchStr - 1; j >= 1 && src[i + j] == pattern[j]; j--) ;
           if (j == 0) return i;
        }
    }
    return -1;
}

Vllt. nicht schön, aber es läuft… :grin:

Also das mit dem template und so weiter kapier ich beim besten Willen nicht.

Mach dir nix draus...

Zumindest hat die Template Variante den Vorteil, dass sie mit ALLEM funktioniert, was man irgendwie in ein Array stopfen kann. Wenn es denn einen brauchbaren == Operator dafür gibt, kann man damit sogar Äpfel in einer Birnenkiste finden.

Man muss ja nicht alles können :stuck_out_tongue:

Danke nochmal für den Tip mit dem Verlust der Längeninfo bei Zeigerübergabe.
Da würd ich sonst heut noch suchen...

combie:
Zumindest hat die Template Variante den Vorteil, dass sie mit ALLEM funktioniert, was man irgendwie in ein Array stopfen kann.

Wobei man auch in C byteweise Vergleiche beliebiger Daten mit void Zeigern machen kann. So funktioniert memcmp().

In C++ sollte man das natürlich nicht mehr tun

Jo Jungs, da kann ich nur noch demütig staunen, worüber ihr redet, und mich meinem Vorredner anschliessen…

postmaster-ino:

  • bin ich aber raus, da ich keine Ahnung habe, was dann Da wirklich abläuft :wink:

Auf dieser Ebene sind Templates nicht so kompliziert. Das wird erst im Zusammenhang mit der STL und komplexerem Code unleserlich

Templates sind Code Generatoren. Man gibt einen generischen Typ an und der Compiler übernimmt alle Arbeit. Dann kann man beliebige Datentypen übergeben und der Compiler erstellt einfach neue Funktionen ohne dass du das siehst

z.B. mit Klassen:

template<typename T>
class Test
{
   T data[10];
};
Test<int> test1;
Test<long> test2;

Und das kannst du auch ohne Templates machen:

A (&haystack)[Acount]

Arrays als Referenzen übergeben. Dann kann man sizeof() machen. Das Problem dabei ist dann normalerweise dass man nur Arrays dieser Größe übergeben kann.
Das Template umgeht das einfach indem es für andere Größen zusätzliche Funktionen erstellt

worüber ihr redet

Einerseits über recht notwendige Grundlagen, hier: Zeiger+Arrays

Und hier drüber:
C++ ist eine Multiparadigmen Sprache.
Und wenn einem das jeweilige Paradigma noch nicht begegnet/bekannt ist, dann schaut man halt, wie das gern als Beispiel genommene Schwein, ins Uhrwerk.

Aber das muss ja kein Endzustand sein.....

Lasst mich mal raten:
Ihr habe beide ein Informatikstudium hinter euch?

Da kann ich leider nicht mithalten.
Dass Zeiger, Referenzen usw.. Grundlagen sind, die ich, trotz Sereniflys (und auch von anderen) unermüdlicher Hilfe noch immer nicht ganz verinnerlicht habe, muss ich leider anerkennen. Schande über mich.

Aber so was wie Paradigmen.... Ehrlich... Bahnhof.
Ich hab vor einer gefühlten Ewigkeit Nachrichtentechnik studiert, und damals gabs nur Turbo Pascal gelehrt. Mit den Jahren fällt man dann über alle möglichen Programmiersprachen drüber...
Wobei ich mich bei SPS und Assembler/Maschinensprache noch am wohlsten fühle.

Mein "Programmierparadigma" hat sich dann im Laufe der Zeit nach folgendem Schema entwickelt.

  • Ich definiere mir ein Programmierziel
  • Welcher Befehlssatz steht mir zur Verfügung?
  • Mit möglichst einfachem Code das Ziel erreichen
  • Den Code so schreiben, dass ich ihn nach 2 Wochen noch verstehe

Und...ja, ich will nicht stehen bleiben. Aber der Aufwand/Nutzen-Faktor soll noch im Rahmen bleiben. Ist und bleibt für mich ein Hobby. (Eines von mehreren)

Und wenn ich mal gar nicht mehr weiter weiß, dann gibts hier super Leute, die mit einer Eselsgeduld weiter helfen. :wink:

Danke für!!!

In einem Studium lernst du das nicht unbedingt. Da geht es größtenteils um allgemeine Dinge. Ich hatte da einen freiwilligen C++ Kurs, aber größtenteils habe ich mir das selbst beigebracht.

Ich denke, die Meisten hier haben sich den größten Teil selbst beigebracht. Es gibt auch noch Bücher.

Gruß Tommy

hk007:
Lasst mich mal raten:
Ihr habe beide ein Informatikstudium hinter euch?

Autodidakt.
Bin also eher sowas wie: Eine eingewiesene Person mit fundiertem Halbwissen.

Habe allerdings auch viele Jahre im Team agieren dürfen.
Verschiedenste Sprachen und Zielsysteme.
So lernt man dann die grundlegenden Konzepte/Pattern und kann sie auch benennen. (oder geht unter)

Frei nach dem Motto:

Alles außer Cobol und Lisp.

OK, kein Informatikprofessor unter euch.
Dann hab ich ja noch Hoffnung für mich.
Aber ich mache damit einfach zu wenig, um meine Kenntnisse entsprechend zu erweitern.

Bei mir ist das eher "gefährliches" Halbwissen

Lisp: War da nicht mal was bei AutoCAD?

Dann hab ich ja noch Hoffnung für mich.

Ja!
Durchaus.

Tipp:
Eigentlich ist es eine Frage der inneren Einstellung:
Solange man noch für sich selber begründet, "warum" man "dies oder das" gerade nicht lernen kann, solange wird das auch nichts.
Das ist recht zuverlässig der Fall.

Das witzige daran:
Es ist ein sich selbst stabilisierendes System/Konzept.
Denn: Jegliches aufzählen dieser Gründe, ist eine Tätigkeit im Rahmen der Selbstsuggestion, und festigt so die Situation.

Leitsatz:

Wer will, findet Wege.
Wer nicht will, findet Gründe.