【问题标题】:bsearch() - Finding a string in an array of structsbsearch() - 在结构数组中查找字符串
【发布时间】:2017-10-07 22:22:28
【问题描述】:

我有一个看起来像这样的结构:

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);

但是,这有点小技巧,而且仅在字符串恰好是结构的第一个成员时才有效。在结构数组中查找字符串并返回指向该结构的指针的更好方法是什么?

【问题讨论】:

  • 您需要实现一个比较函数,该函数将知道dictionary_t 类型结构并传递它而不是strcmp。在你的情况下这很容易 - 只是 strcmp 的包装。
  • 自定义比较函数的示例位于standards page 的底部,用于bsearch()
  • 这实际上是错误的,您需要使用正确的签名编写自己的比较函数,然后将 const void 指针分配给结构的 const bointers 并在成员上调用 strncmp()
  • 感谢您的快速回复:)。我将阅读一些关于编写比较函数的内容并试一试。

标签: c string struct bsearch


【解决方案1】:

您应该实现自己的比较器函数并将其传入。这里要记住的最重要(非平凡)的事情是根据standard

实现应确保第一个参数始终是指向键的指针。

这意味着您可以编写一个比较器来比较字符串,例如targetdictionary_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

【讨论】:

  • 感谢您的快速和翔实的回答。现在更有意义了。 :)
  • @Jens。固定的。我改用sizeof(((dictionary_t *)0)->word)
  • 这里不需要投:strncmp((const char *)s ...
  • @alk。你说的对。我最初是在比较两个结构,那是一个遗物。当我在它的时候,还制作了 dict 演员 const
猜你喜欢
  • 2020-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 2014-05-27
  • 2020-08-27
相关资源
最近更新 更多