Wer schon einmal in die Verlegenheit gekommen ist, Binärdateien patchen zu müssen, wird vermutlich einen HEX Editor zu Hilfe genommen haben um Bytesequenzen zu finden und zu überschreiben. C unterstützt das Überschreiben von Sequenzen direkt im Stream, sodass es insbesondere bei großen Dateien nicht nötig ist, den gesamten Dateiinhalt zu lesen und in einen Cache zu schreiben.
Die implementierten Funktionen
Es ist sowohl möglich den Dateiname zu übergeben, als auch einen bereits geöffneten FILE Stream.
Wird ein Dateiname übergeben, beginnt die Suche am Dateianfang im Fall von
Wird ein FILE Stream übergeben, beginnt die Suche bei der derzeitigen Position des Streamcursors, was ein Weitersuchen derselben oder einer anderen Sequenz in der Datei ermöglicht.
Speziell für Windows gibt es zusätzlich die
Im Download-Paket sind die beiden Dateien
Detaillierte Funktionsbeschreibungen finden sich in der Headerdatei. In der ebenfalls im Paket enthaltenen
Beispiel
Dateiinhalt von "test.txt":
Aufgabe:
Suche das letzte Vorkommen von "xx" vor "ABC", wenn die Häufigkeit von "xx"-Folgen vor "ABC" und ihre genaue Positionen variabel sind.
Ersetze die gefundene Folge durch "ZZ".
Lösung:
Neuer Dateiinhalt von "test.txt":
Die implementierten Funktionen
ffind
(für die Vorwärtssuche) und frfind
(für die Rückwärtssuche) lesen lediglich Teile der Datei und nutzen den Rabin-Karp Suchalgorithmus um die "Nadel im Heuhaufen" zu finden. Bei Erfolg wird der Streamcursor vor die gefundene Sequenz gestellt.Es ist sowohl möglich den Dateiname zu übergeben, als auch einen bereits geöffneten FILE Stream.
Wird ein Dateiname übergeben, beginnt die Suche am Dateianfang im Fall von
ffind
, bzw. am Dateiende im Fall von frfind
.Wird ein FILE Stream übergeben, beginnt die Suche bei der derzeitigen Position des Streamcursors, was ein Weitersuchen derselben oder einer anderen Sequenz in der Datei ermöglicht.
Speziell für Windows gibt es zusätzlich die
ffindw
und frfindw
Funktionen. Einziger Unterschied ist, dass der Dateiname als String von wchar_t
übergeben wird, um auch auf Windows Betriebssystemen nicht-ASCII Dateinamen zu unterstützen.Im Download-Paket sind die beiden Dateien
findinfile.h
und findinfile.c
mit den Funktionen:FILE *ffind(const char *file_name, FILE *file_stream, const void *needle, long needle_cnt);
FILE *ffindw(const wchar_t *file_name, FILE *file_stream, const void *needle, long needle_cnt);
(nur Windows)FILE *frfind(const char *file_name, FILE *file_stream, const void *needle, long needle_cnt);
FILE *frfindw(const wchar_t *file_name, FILE *file_stream, const void *needle, long needle_cnt);
(nur Windows)Detaillierte Funktionsbeschreibungen finden sich in der Headerdatei. In der ebenfalls im Paket enthaltenen
main.c
befinden sich Testfunktionen, die auch als Beispiele für die Nutzung herangezogen werden können.Beispiel
Dateiinhalt von "test.txt":
oooxxooooxxooxxooooxxoABCooxxoooooxxoo
Aufgabe:
Suche das letzte Vorkommen von "xx" vor "ABC", wenn die Häufigkeit von "xx"-Folgen vor "ABC" und ihre genaue Positionen variabel sind.
Ersetze die gefundene Folge durch "ZZ".
Lösung:
C:
#include "findinfile.h"
int main(void) {
FILE *stream = ffind("test.txt", NULL, "ABC", 3); // Suche nach "ABC" vom Dateianfang.
if (stream == NULL)
return 1;
if (frfind(NULL, stream, "xx", 2) == NULL || // Suche von der gefundenen Position rückwärts nach "xx".
fwrite("ZZ", 1, 2, stream) != 2) // Überschreibe mit "ZZ"
{
fclose(stream);
return 1;
}
fclose(stream);
return 0;
}
oooxxooooxxooxxooooZZoABCooxxoooooxxoo