【发布时间】:2017-01-18 23:29:50
【问题描述】:
我有一个二进制数据文件,其中散布着各种字符串。我正在尝试编写一个 C 代码来查找文件中用户指定字符串的第一次出现。 (我知道这可以用 bash 完成,但出于其他原因我需要 C 代码。)目前的代码是:
#include <stdio.h>
#include <string.h>
#define CHUNK_SIZE 512
int main(int argc, char **argv) {
char *fname = argv[1];
char *tag = argv[2];
FILE *infile;
char *chunk;
char *taglcn = NULL;
long lcn_in_file = 0;
int back_step;
fpos_t pos;
// allocate chunk
chunk = (char*)malloc((CHUNK_SIZE + 1) * sizeof(char));
// find back_step
back_step = strlen(tag) - 1;
// open file
infile = fopen(fname, "r");
// loop
while (taglcn == NULL) {
// read chunk
memset(chunk, 0, (CHUNK_SIZE + 1) * sizeof(char));
fread(chunk, sizeof(char), CHUNK_SIZE, infile);
printf("Read %c\n", chunk[0]);
// look for tag
taglcn = strstr(chunk, tag);
if (taglcn != NULL) {
// if you find tag, add to location the offset in bytes from beginning of chunk
lcn_in_file += (long)(taglcn - chunk);
printf("HEY I FOUND IT!\n");
} else {
// if you don't find tag, add chunk size minus back_step to location and ...
lcn_in_file += ((CHUNK_SIZE - back_step) * sizeof(char));
// back file pointer up by back_step for next read
fseek(infile, -back_step, SEEK_CUR);
fgetpos(infile, &pos);
printf("%ld\n", pos);
printf("%s\n\n\n", chunk);
}
}
printf("%ld\n", lcn_in_file);
fclose(infile);
free(chunk);
}
如果您想知道,back_step 用于处理不太可能发生的问题,即相关字符串被chunk 边界分割。
我要检查的文件大小约为 1Gb。问题是,由于某种原因,我可以在前 9000 个字节左右找到任何字符串,但除此之外,strstr 不知何故没有检测到任何字符串。也就是说,如果我在文件中查找超过 9000 字节左右的字符串,strstr 不会检测到它。代码会读取整个文件,但始终找不到搜索字符串。
我尝试将 CHUNK_SIZE 从 128 更改为 50000,但结果没有变化。我也尝试过改变back_step。当strstr 找不到字符串时,我什至输入了诊断代码以逐个字符打印出chunk,而且果然,字符串正是它应该在的位置。 pos 的诊断输出始终正确。
谁能告诉我哪里出错了? strstr 是不是在这里用错了工具?
【问题讨论】:
-
虽然这不一定是问题,但为了使用任意搜索(如来自
SEEK_CUR的负偏移),您必须以二进制模式打开流。您的信息流以文本模式打开。 -
另外,您是否有机会搜索二进制文件,即其中包含零字节的文件?
-
@AnT 是的,大概就是这样。谢谢。