【问题标题】:bsearch() on an array of strings in Cbsearch() 在 C 中的字符串数组上
【发布时间】:2018-07-13 23:44:27
【问题描述】:

我在 C 中实现了一个代码,以便将一个字符串复制到一个字符数组 ( string ) 中,然后对其进行 bsearch。但出乎意料的是,对于应该为真的结果,bsearch 返回假。 我猜这与我在插入过程中如何首先插入字符串有关。您可以将其视为对 btree 的叶节点的插入和搜索。

我在多文件框架中对此进行编码,因此无法发布所有代码。贴出相关部分

字符串数组的结构便于可视化 -

array of strings ( array of array of chars ) 
                            --
                          0 -- array of characters ( size may be 5 )  
                          1 -- array of characters ( size may be 7 ) 
                          2 -- array of characters ( size may be 10 )

or

keys = [
         [ s t r i n g 1 ]
         [ s t r i n g T w o ]
         [ s t r i n g T H R E E ]
       ]

要插入的函数 -

void insert_in_leaf_node(struct leaf_node * node, u32 len, u8 * key){
    if (node->no_of_keys > 1 ) {
       if (!search_in_fat(node, len, key)) {
            node->keys[node->no_of_keys] = (char *) malloc(sizeof(char) * len);
            strncpy(node->keys[node->no_of_keys], (char *) key, len);                                                              // copy key to array
            node->keys[node->no_of_keys][len] = '\0';
            node->no_of_keys += 1;
            qsort(node->keys, (size_t) node->no_of_keys, sizeof(char *), cstring_cmp);                                          // sort alphabetically to enable bsearch later
        }
    } else {
        node->keys[node->no_of_keys] = (char *) malloc(sizeof(char) * len);
        strncpy(node->keys[node->no_of_keys], (char *) key, len);                                                              // copy key to array
        node->keys[node->no_of_keys][len] = '\0';
        node->no_of_keys += 1;
        qsort(node->keys, (size_t) node->no_of_keys, sizeof(char *), cstring_cmp);                                          // sort alphabetically to enable bsearch later
    }
}

要搜索的代码 -

bool search_in_fat(struct leaf_node * node, u32 len, u8 * key){
    if(!bsearch(key,node->keys,(size_t)node->no_of_keys, sizeof( char * ),(int(*)(const void*,const void*)) strcmp)) return false;
    return true;
}

插入函数中使用的cstring_cmp函数 -

int cstring_cmp(const void *a, const void *b)
{
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    return strcmp(*ia, *ib);
    /* strcmp functions works exactly as expected from
    comparison function */
}

如果有人想知道 key 中的内容,这里是一个 key 数组是如何更早地填充的,并且每次都使用单独的 key 调用 set/get 函数(set/get 函数调用上述函数)

用于从文件中加载跟踪以生成键数组的代码 - (__samples 持有密钥)

bool
load_trace(const char * const filename)
{
  char * buf = NULL;
  size_t size = 0;
  FILE * fin = fopen(filename, "r");
  if (fin == NULL) return false;
  u64 i = 0;
  // count for lines
  while (getline(&buf, &size, fin) >= 1) {
    i++;
  }
  rewind(fin);
  __samples = malloc(sizeof(char *) * i);
  __sizes = malloc(sizeof(u32) * i);
  __nr_samples = i;
  ssize_t len = 0;
  i = 0;
  while ((len = getline(&buf, &size, fin)) >= 1) {
    if (buf[len-1] == '\n') { // remove trailing '\n'
      len--;
      buf[len] = '\0';
    }
    __samples[i] = strdup(buf);
    __sizes[i] = len;
    i++;
  }
  free(buf);
  fclose(fin);
  return true;
}

P.S : 这部分不是我写的,是我前辈在搭建框架的时候写的。

可能是什么问题?我已经做了很多谷歌搜索,但还没有积极的结果。

谢谢!

【问题讨论】:

  • strncpy(node->keys[node->no_of_keys], (char *) key, len); 不是在复制一个字符串,只是一个字符数组。 strcmp() 需要 字符串。欲了解更多信息,请发帖minimal reproducible example
  • @chux 不是字符串字符数组,无论如何对于 c?我应该用什么来代替strncpy?内存?并且发布完整的代码将是巨大的代码。这就是为什么发布相关部分。
  • 在您发布的内容和完整代码之间是minimal reproducible example。该帖子没有按原样明确回答。
  • @chux 我明白了。你能告诉我你到底想从代码中得到什么吗?我可以给你我的 githib 链接,这样你就可以根据需要查看完整的代码。它是一个多文件框架。

标签: c data-structures malloc c11 bsearch


【解决方案1】:

您不能将strcmp() 作为bsearch() 的比较函数传递。该函数需要指向要比较的元素的指针(在这种情况下是指向字符串指针的指针,尽管函数参数的实际类型需要是const void *),而strcmp() 需要指向字符串的指针.有一个额外的间接层它无法处理。

您没有显示函数,但您使用的 cstring_cmp() 函数与 qsort() 可能可以使用。

bsearch() 比较函数的第一个参数是作为键给出的指针,第二个参数是指向正在比较的数组的当前元素的指针,其中 qsort() 比较函数,两个参数都是指针到元素。因此,如果您将bsearch() 的关键参数设为指向您正在寻找的东西的指针,那么两者都将使用相同的功能。换句话说,bsearch(&key, ...) 是好的,bsearch(key, ...) 不是。您还可以使用bsearch() 特定的比较函数来处理第二种情况。示例见https://stackoverflow.com/a/15824981/9952196

【讨论】:

  • 嗨,我刚刚为 cstring_cmp 函数添加了代码。你能看一下,如果你认为这是正确的,请告诉我?同时我也会尝试使用它。
  • 我认为你是对的。那可能刚刚解决了这个问题。我会做更全面的测试然后回来。谢谢!
  • @Nirmik 看起来像是与 qsort() 和字符串数组一起使用的合适函数,是的。如果您正在搜索的元素是使用其地址传递的(我需要返回并改写我的答案,因为我忘记了那个警告),它也可以与 bsearch() 一起使用,例如 bsearch(&key, ...)
猜你喜欢
  • 2017-10-07
  • 1970-01-01
  • 2015-03-02
  • 2012-03-20
  • 2013-03-27
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 2013-08-16
相关资源
最近更新 更多