在C

时间:2018-07-13 23:44:28

标签: c data-structures malloc c11 bsearch

我正在用C实现代码,以便将一个字符串复制为一个字符数组(string),然后对其进行bsearch。但是出乎意料的是,对于应该为真的结果,bsearch返回false。 我猜想这与我在插入过程中首先将字符串插入的方式有关。您可以将其视为插入并在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 */
}

万一有人想知道键中有什么,这里是如何填充键数组的方式,并且每次使用单独的键调用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:这部分不是我编写的,而是我上级在构建框架时编写的。

可能是什么问题?我已经进行了大量的谷歌搜索,但尚未取得积极成果。

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

bsearch()比较函数的第一个参数是作为键给出的指针,第二个参数是指向要比较的数组的当前元素的指针,其中带有qsort()比较函数,这两个参数都是指向元素的指针。因此,如果将bsearch()的key参数作为指向所要查找内容的指针,则两者都可以使用相同的功能。换句话说,bsearch(&key, ...)很好,bsearch(key, ...)不好。您还可以使用特定于bsearch()的比较功能,以处理第二种情况。有关示例,请参见https://stackoverflow.com/a/15824981/9952196