如果指针包含在内存中,则可以假设您可以分配一个相同大小的对象来读取(例如char input_array[needle_size];
)。
要开始搜索过程,请使用文件中的字节填充该对象(例如size_t sz = fread(input_array, 1, input_size, input_file);
)并尝试匹配(例如if (sz == needle_size && memcmp(input_array, needle, needle_size) == 0) { /* matched */ }
.
如果匹配失败或者您想在成功匹配后继续搜索,请将位置向前推进一个字节(例如memmove(input_array, input_array + 1, input_size - 1); input_array[input_size - 1] = fgetc(input_file);
,再试一次。
在评论中提出了一个担忧,即这个想法复制了太多字节。虽然我不认为这种担忧有很大的好处(因为没有证据表明有重要价值),但可以通过使用循环数组来避免复制;我们在该边界之前和之后插入新字符pos % needle_size
并比较区域,就好像它们分别是尾部和头部一样。例如:
void find_match(FILE *input_file, char const *needle, size_t needle_size) {
char input_array[needle_size];
size_t sz = fread(input_array, 1, needle_size, input_file);
if (sz != needle_size) {
// No matches possible
return;
}
setvbuf(input_file, NULL, _IOFBF, BUFSIZ);
unsigned long long pos = 0;
for (;;) {
size_t cursor = pos % needle_size;
int tail_compare = memcmp(input_array, needle + needle_size - cursor, cursor),
head_compare = memcmp(input_array + cursor, needle, needle_size - cursor);
if (head_compare == 0 && tail_compare == 0) {
printf("Match found at offset %llu\n", pos);
}
int c = fgetc(input_file);
if (c == EOF) {
break;
}
input_array[cursor] = c;
pos++;
}
}