bsearch() - 在结构数组中查找字符串
bsearch() - Finding a string in an array of structs
我有一个看起来像这样的结构:
typedef struct dictionary_t{
char word[30];
int foo;
int bar;
} dictionary_t;
构成有序数组:
dictionary_t dictionary[100];
我想使用 bsearch() 在此数组中搜索字符串并获取指向该结构的指针。到目前为止,这已经奏效:
dictionary_t* result;
char target[30] = "target";
result = bsearch(&target, dictionary, dict_length, sizeof(dictionary_t), (int(*)(const void*,const void*)) strcmp);
然而,这有点 hack,仅在字符串恰好是结构的第一个成员时才有效。在结构数组中查找字符串和 return 指向该结构的指针的更好方法是什么?
您应该实现自己的比较器函数并将其传入。这里要记住的最重要(重要)的事情是,根据 standard、
The implementation shall ensure that the first argument is always a pointer to the key.
这意味着您可以编写一个比较器来比较 target
等字符串和 dictionary_t
对象。这是一个将结构与字符串进行比较的简单函数:
int compare_string_to_dict(const void *s, const void *d) {
return strncmp(s, ((const dictionary_t *)d)->word, sizeof(((dictionary_t *)0)->word));
}
然后您可以按名称将其作为普通函数指针传递给 bsearch
:
result = bsearch(target, dictionary, dict_length, sizeof(dictionary_t), compare_string_to_dict);
请注意,target
不需要传入其地址,因为它不再模拟结构。
如果您想知道,sizeof(((dictionary_t *)0)->word)
是在 dictionary_t
中获取 word
大小的惯用方法。您也可以执行 sizeof(dictionary[0].word)
或定义一个等于 30 的常量。它来自 here.
我有一个看起来像这样的结构:
typedef struct dictionary_t{
char word[30];
int foo;
int bar;
} dictionary_t;
构成有序数组:
dictionary_t dictionary[100];
我想使用 bsearch() 在此数组中搜索字符串并获取指向该结构的指针。到目前为止,这已经奏效:
dictionary_t* result;
char target[30] = "target";
result = bsearch(&target, dictionary, dict_length, sizeof(dictionary_t), (int(*)(const void*,const void*)) strcmp);
然而,这有点 hack,仅在字符串恰好是结构的第一个成员时才有效。在结构数组中查找字符串和 return 指向该结构的指针的更好方法是什么?
您应该实现自己的比较器函数并将其传入。这里要记住的最重要(重要)的事情是,根据 standard、
The implementation shall ensure that the first argument is always a pointer to the key.
这意味着您可以编写一个比较器来比较 target
等字符串和 dictionary_t
对象。这是一个将结构与字符串进行比较的简单函数:
int compare_string_to_dict(const void *s, const void *d) {
return strncmp(s, ((const dictionary_t *)d)->word, sizeof(((dictionary_t *)0)->word));
}
然后您可以按名称将其作为普通函数指针传递给 bsearch
:
result = bsearch(target, dictionary, dict_length, sizeof(dictionary_t), compare_string_to_dict);
请注意,target
不需要传入其地址,因为它不再模拟结构。
如果您想知道,sizeof(((dictionary_t *)0)->word)
是在 dictionary_t
中获取 word
大小的惯用方法。您也可以执行 sizeof(dictionary[0].word)
或定义一个等于 30 的常量。它来自 here.