Frage

Ich habe eine binäre Datei, die ich geladen habe ein NSData Objekt. Gibt es eine Möglichkeit, eine Folge von Zeichen, ‚abcd‘ zum Beispiel innerhalb dieser binären Daten zu lokalisieren und das Rück der Offset ohne die gesamte Datei in einen String zu konvertieren? Scheint, wie es eine einfache Antwort sein sollte, aber ich bin nicht sicher, wie es zu tun. Irgendwelche Ideen?

Ich tue dies auf iOS 3, so habe ich nicht -rangeOfData:options:range: zur Verfügung.

Ich werde diese ein bis sechzehn Otto zu vergeben für die Annahme, strstr. Ich ging und den Quellcode für die Funktion C strstr gefunden und neu geschrieben es auf eine feste Länge Byte-Array zu arbeiten - die übrigens verschieden von einem char-Array ist, wie es nicht beendet ist null. Hier ist der Code ich am Ende mit:

- (Byte*)offsetOfBytes:(Byte*)bytes inBuffer:(const Byte*)buffer ofLength:(int)len;
{
    Byte *cp = bytes;
    Byte *s1, *s2;

    if ( !*buffer )
        return bytes;

    int i = 0;
    for (i=0; i < len; ++i)
    {
        s1 = cp;
        s2 = (Byte*)buffer;

        while ( *s1 && *s2 && !(*s1-*s2) )
            s1++, s2++;

        if (!*s2)
            return cp;

        cp++;
    }

    return NULL;
}

Dies gibt einen Zeiger auf das erste Vorkommen von Bytes, das, was ich bin auf der Suche nach, in Puffern, den Byte-Array, das Bytes enthalten sollte.

Ich nenne es wie folgt aus:

// data is the NSData object
const Byte *bytes = [data bytes];
Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]];
War es hilfreich?

Lösung

Konvertieren Sie Ihre Teilkette auf ein NSData Objekt und für das Bytes in den größeren NSData Suche mit rangeOfData:options:range: . Stellen Sie sicher, dass die Zeichenfolge Codierungen Spiel!

Auf dem iPhone, wenn dies nicht verfügbar ist, können Sie dies selbst zu tun haben. Die C-Funktion strstr() gibt Ihnen einen Zeiger auf das erste Auftreten eines Musters innerhalb des Puffers (solange weder NULL-Werte enthalten!), Aber nicht der Index. Hier ist eine Funktion, die sollte die Arbeit machen (aber keine Versprechungen, denn ich habe nicht versucht, es tatsächlich läuft ...):

- (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack
{
    const void* needleBytes = [needle bytes];
    const void* haystackBytes = [haystack bytes];

    // walk the length of the buffer, looking for a byte that matches the start
    // of the pattern; we can skip (|needle|-1) bytes at the end, since we can't
    // have a match that's shorter than needle itself
    for (NSUInteger i=0; i < [haystack length]-[needle length]+1; i++)
    {
        // walk needle's bytes while they still match the bytes of haystack
        // starting at i; if we walk off the end of needle, we found a match
        NSUInteger j=0;
        while (j < [needle length] && needleBytes[j] == haystackBytes[i+j])
        {
            j++;
        }
        if (j == [needle length])
        {
            return i;
        }
    }
    return NSNotFound;
}

Dies läuft in so etwas wie O (nm), wobei n die Pufferlänge ist, und m ist die Größe der Teilkette. Es ist geschrieben mit NSData aus zwei Gründen zu arbeiten: 1.) Das ist, was man in der Hand zu haben scheint, und 2) die Objekte bereits kapseln sowohl das tatsächliche Bytes, und die Länge des Puffers

Andere Tipps

Wenn Sie Snow Leopard verwenden, eine bequeme Art und Weise ist die neue -rangeOfData: Optionen: Bereich: Methode in NSData , die den Bereich des ersten Auftretens eines Stücks Daten zurückgibt . Andernfalls können Sie den Inhalt des NSData Zugriff selbst seine -bytes Methode Ihre eigene Suche durchzuführen.

Ich hatte das gleiche Problem. Ich löste es um die andere Art und Weise zu tun, im Vergleich zu den Vorschlägen.

zuerst, umformatieren ich die Daten (nehmen Ihre NSData in var rawFile gespeichert) mit:

NSString *ascii = [[NSString alloc] initWithData:rawFile encoding:NSAsciiStringEncoding];

Sie können nun leicht String Suchanfragen wie ‚ABCD‘ tun oder was auch immer Sie wollen die NSScanner-Klasse und den ASCII-String an den Scanner vorbei. Vielleicht ist dies nicht wirklich effizient, aber es funktioniert, bis die -rangeOfData Methode für das iPhone verfügbar sein wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top