gpt4 book ai didi

c - strstr 的微妙之处?

转载 作者:行者123 更新时间:2023-12-04 11:33:27 28 4
gpt4 key购买 nike

我有一个二进制数据文件,其中散布着各种字符串。我正在尝试编写 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 是不是用错了工具?

最佳答案

既然你说你的文件是二进制的,strstr()将在文件中的第一个空字节处停止扫描。

如果你想在二进制数据中寻找模式,那么 memmem()功能是适当的,如果它是可用的。它在 Linux 和其他一些平台(BSD、macOS 等)上可用,但未定义为标准 C 或 POSIX 的一部分。它与 memcpy()strstr() 的关系大致相同。熊strcpy() .


请注意,您的代码应该检测 fread() 读取的字节数,并且只搜索它。

char   *tag = …;     // Identify the data to be searched for
size_t taglen = …; // Identify the data's length (maybe strlen(tag))
int nbytes;
while ((nbytes = fread(chunk, 1, (CHUNK_SIZE + 1), infile)) > 0)
{

tagcln = memmem(chunk, nbytes, tag, taglen);
if (tagcln != 0)
…found it…

}

目前还不清楚为什么您在 block 大小上有 +1fread() 函数不会在数据末尾添加空字节或类似内容。我保持这方面不变,但可能不会在我自己的代码中使用它。

最好注意识别跨越两个 block 之间边界的标签。

关于c - strstr 的微妙之处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41731296/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com