如何解决使用结构数组进行 bsearch
我有一个已经使用 qsort
排序的结构数组。我正在尝试在 struct 中搜索名称,但它总是返回 NULL
。发生这种情况的原因是什么?
这是我的代码:
#include "card.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int cmpname (const void *pa,const void *pb) {
const char *p1 = pa;
const index_t * const *p2 = pb;
//printf("Comparing: %s %s\n",p1,(char*)*p2);
return strcmp((p1),(*p2)->name);
}
int main(int argc,char **argv)
{
unsigned length;
int i = 0;
int length_multiplier = 0;
char *input = NULL;
char *pItem;
index_t **indexs = NULL;
FILE *input_file;
if((input_file = fopen("index.bin","rb")) != NULL)
{
// GETS USER INPUT
printf(">> ");
size_t num_read = 0;
getline(&input,&num_read,stdin);
printf("Searching for: %s\n",input);
if(*input != 113)
{
// READING FILE AND ADDING ENTRIES INTO STRUCT
//int *key;
//int *pItem;
//input_file = fopen("index.bin","rb");
if (input_file == NULL)
{
printf("ERROR OPENING FILE\n");
free(indexs);
fclose(input_file);
return 1;
}
// READS THE INPUT FILE
for(i = 0; fread(&length,sizeof(unsigned int),1,input_file) != 0; i++)
{
length_multiplier++;
indexs = realloc(indexs,sizeof(index_t *) * length_multiplier);
indexs[i] = malloc(sizeof(index_t));
indexs[i]->name = malloc(sizeof(char) * length + 1);
fread(indexs[i]->name,sizeof(char),length,input_file);
indexs[i]->name[length] = 0;
fread(&indexs[i]->offset,sizeof(long),input_file);
}
for(i = 0; i < length_multiplier; i++)
{
printf("%s\n",indexs[i]->name);
}
printf("Searching for: %s\n",input);
pItem = (char*) bsearch(&input,indexs,length_multiplier,sizeof(indexs),cmpname);
if(pItem == NULL)
{
printf("%s not found\n",pItem);
}
else
{
printf("found %s\n",pItem);
}
//FREEING MEMORY
for(int i = 0; i < length_multiplier; i++)
{
free(indexs[i]->name);
free(indexs[i]);
}
free(indexs);
free(input);
//fread(card[0]->id,sizeof(u_int32_t),input_file);
fclose(input_file);
return 0;
}
else
{
printf("Exiting...\n");
return 1;
}
}
else
{
fprintf(stderr,"./parser: cannot open(%s%s%s): No such file or directory","\"",argv[1],"\"");
return 1;
}
}
这是我声明的结构:
typedef struct index {
char *name;
long offset;
} index_t;
解决方法
比较器函数应该比较数组中的两个,而不是两个不同的东西。在您的情况下,您想要比较两个 index_t *
,而不是一个 index_t *
和一个 char *
。所以它可能看起来像这样:
int cmpname (const void *pa,const void *pb) {
const index_t * const *p1 = pa;
const index_t * const *p2 = pb;
//printf("Comparing: %s %s\n",p1,(char*)*p2);
return strcmp((*p1)->name,(*p2)->name);
}
,
变量 indexs
声明如下
index_t **indexs = NULL;
并指向元素类型为 index_t *
的数组的第一个元素。
所以在调用 bsearch
pItem = (char*) bsearch(&input,indexs,length_multiplier,sizeof(indexs),cmpname);
接受结果的对象应具有 index_t **
类型,因为该函数返回一个指向目标元素的指针。
因此变量 pItem
应声明为
index_t **pItem;
由于数组元素的类型为 index_t *
,因此您必须使用参数 sizeof( index_t * )
而不是 sizeof( indexs )
。
另一方面,第一个参数也应该是指向 index_t *
类型对象的指针。
因此在调用函数之前,您可以编写例如
index_t input_item = { .name = input,.offset = 0 };
index_t *p_input_item = &input_item;
bsearch
的调用看起来像
pItem = bsearch( &p_input_item,sizeof( index_t * ),cmpname );
然后你可以写
if(pItem == NULL)
{
printf("%s not found\n",input);
}
else
{
printf("found %s\n",input);
}
最后比较函数看起来像
int cmpname (const void *pa,const void *pb) {
const index_t * const *p1 = pa;
const index_t * const *p2 = pb;
return strcmp( ( *p1 )->name,(*p2)->name );
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。