使用memcmp比较0字节的缓冲区

时间:2019-03-26 11:55:06

标签: c

我试图使用memcmp逐字节比较文件中的2个文本,然后将它们都读入内存,将一个文件读入缓冲区(char *或char [],都尝试了)。问题是,我读入缓冲区的文件有很多0字节,这使他在第一个0字节处停止,认为它是一个以零结尾的零,这会导致分段错误。我如何使该功能即使在有0个字节的情况下也保持比较字节呢?

我已经尝试检查缓冲区是否已满,我逐字节打印该缓冲区,它显示了所有字节,包括0字节。当我使用printf(“%s”,buffer)完全打印时,我只得到第一个字节(第二个字节是0字节)。

void detect_virus(char *buffer, unsigned int size){
    link* l = (link*) malloc(sizeof(link));
    load(l);
    unsigned int location = 0;
    while(l != NULL){
        location = 0;
        while(location < size - l->vir->SigSize){
            int isVirus = memcmp(buffer + location, l->vir->sig, l->vir->SigSize);
            if(isVirus == 0)
                printf("%d, %s, %d\n", location, l->vir->virusName, l->vir->SigSize);
            location++;
        }
    }
    free(l);
}

void detect(link* list){
    char filename[50];
    fgets(filename, 50, stdin);
    sscanf(filename, "%s", filename);
    FILE* file = fopen(filename, "rb");
    char* buffer = (char*) malloc(10000);
    fseek(file, 0, SEEK_END);
    unsigned int size = ftell(file);
    fseek(file, 0, SEEK_SET);
    fread(buffer, 1, size, file);
    detect_virus(buffer, size);
    fclose(file);
}

我第一次调用memcmp函数时遇到了分割错误,而不是完全比较文本。有任何解决办法的想法吗?

修改 load函数的代码:

void load(link* list){
    printf("Enter Viruses file name: \n");
    char* filename = (char*) malloc(100);
    fgets(filename, 100, stdin);
    sscanf(filename, "%s", filename);
    FILE* file = fopen(filename, "r");

    while(!feof(file)){
        short length = 0;
        fread(&length, 2, 1, file);
        if(length == 0)
            break;
        struct virus* v = (struct virus*)malloc(length);
        fseek(file, -2, SEEK_CUR);
        fread(v, length, 1, file);
        v->SigSize = v->SigSize - 18;
        list_append(list, v);
    }
    list = list->nextVirus;
    free(filename);
    fclose(file);
}

请注意,我之前已经测试过该功能,并且可以正常工作。

编辑 我发现了问题,谢谢大家!

1 个答案:

答案 0 :(得分:0)

7.21.6.7 The sscanf function, paragraph 2 of the C standard(在我的脑海中):

  

sscanf函数等效于fscanf,不同之处在于输入是从字符串(由参数s指定)中获得的,而不是从流中获得的。到达字符串的结尾等同于遇到fscanf函数的文件结尾。 如果在重叠的对象之间进行复制,则行为是不确定的。

请注意加粗的部分。

在您的代码中:

sscanf(filename, "%s", filename);

filename数组肯定与filename数组重叠,因此调用了未定义的行为。

删除该行代码。

您还需要添加错误检查,尤其是检查fopen()的返回值是否不是NULL