0

您好我正在使用 bsearch 在结构中的字符串数组中搜索目标字符串并返回字符串的索引。但是,到目前为止它总是返回 NULL,我很确定我获取数组索引的方式也不正确:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_ITEM_SIZE 10
#define MAX_NAME_LEN 20

typedef struct fruit_shelf_s {
    char fruit_name[MAX_NAME_LEN + 1]; // +1 for null
    int max_shelf_size;
    int current_shelf_occupied;
} fruit_shelf_t;

typedef struct food_aisle_s {
    fruit_shelf_t fruits[MAX_ITEM_SIZE];
} food_aisle_t;

void load_fruit_shelf(food_aisle_t *food_aisle, char sample[MAX_ITEM_SIZE][MAX_NAME_LEN]) {
    for(int i; i < MAX_ITEM_SIZE; i++){
        // buffer siE large enough so it does not over flow
        strncpy(food_aisle->fruits[i].fruit_name, sample[i], strlen(sample[i])+1);
    }
    for (int j = 0; j < MAX_ITEM_SIZE; j++) {
        printf("%s\n", food_aisle->fruits[j].fruit_name);
    }   
}

int myStrCmp(const void *s1, const void *s2) {
    printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, *(char **)s1, s2, *(char**)s2);
    return strcmp(*(char **) s1, *(char **) s2);
}

int binary_search(food_aisle_t* food_aisle, char *key){
    char *buff = (char*)bsearch(&key, food_aisle->fruits, MAX_ITEM_SIZE, sizeof(food_aisle_t), (int(*)(const void*,const void*)) strcmp);
    if(!buff){
        int index = (buff - food_aisle->fruits[0].fruit_name) / sizeof(food_aisle->fruits[0]);
        printf("Found key = %s at index = %d.\n", buff, index);
        return 0;
    } else {
        printf("Did not find key = %s\n", key);
        return -1;
    }
}

char sample[MAX_ITEM_SIZE][MAX_NAME_LEN] = {"Apple", "Banana", "Orange", "Grape", "Strawberry", "Pineapple", "Jackfruit", "Lemon", "Lime", "Watermelon"};

int main () {
    food_aisle_t food_aisle;
    // Empty the array;
    for (int i = 0; i < MAX_ITEM_SIZE; i++) {
        memset(food_aisle.fruits[0].fruit_name, 0, sizeof(food_aisle.fruits[i].fruit_name));
    }

    // load the array
    load_fruit_shelf(&food_aisle, sample);

    char *key = "Orange";
    int num = binary_search(&food_aisle, key);
    if(num == 0){
        printf("key found");
    } else {
        printf("key not found");
    }

    return(0);
}

所以我不确定我得到 NULL 的原因是否是因为字符串比较函数。所以我写信myStrCmp看看能不能看到数组的地址。但是我遇到了段错误:

Apple
Banana
Orange
Grape
Strawberry
Pineapple
Jackfruit
Lemon
Lime
Watermelon
Segmentation fault (core dumped)

我尝试了这些参数,但我仍然得到 NULL:

// change to double pointer to reference to the array of string
char **buff = (char**)bsearch(&key, food_aisle->fruits, MAX_ITEM_SIZE, sizeof(food_aisle_t*), (int(*)(const void*,const void*)) strcmp);

// change the size type the searching element to sizeof(fruit_shelf_t*)
char *buff = (char*)bsearch(&key, food_aisle->fruits, MAX_ITEM_SIZE, sizeof(fruit_shelf_t*), (int(*)(const void*,const void*)) strcmp);

// change the size type the searching element to sizeof(char*)
char *buff = (char*)bsearch(&key, food_aisle->fruits, MAX_ITEM_SIZE, sizeof(char*), (int(*)(const void*,const void*)) strcmp);

至于获取字符串的索引,我认为下面的想法应该可行,但我无法验证它,因为我无法得到正确的搜索结果。有时我会得到明显错误的负值:

index = (result_element_add - start_add_of_the_array) / size_of_the_objects_in_the_array

我尝试了以下替代方案:

// Try 1:
int index = (buff - food_aisle->fruits[0].fruit_name) / sizeof(food_aisle->fruits[MAX_ITEM_SIZE]);

回来:

Found key = (null) at index = 333807782.
key found
// Try 2:
int index = (buff - food_aisle->fruits[0].fruit_name) / sizeof(food_aisle->fruits[MAX_ITEM_SIZE].fruit_name);

回来:

Found key = (null) at index = -319396745.
key found
// Try 3:
int index = (buff - food_aisle->fruits[0].fruit_name) / sizeof(food_aisle->fruits[0]);

回来:

Found key = (null) at index = 233548559.
key found

这里的使用可能有什么问题bsearch()

4

1 回答 1

0
  1. 你正在传递strcmpbsearch. strcmp接受const char*参数,bsearch使用const void*.
  2. 你正在传递strcmpbsearch. 它比较字符串,而不是fruit_shelf_t.
  3. myStrCmp仍然比较字符串,而fruit_shelf_t不是key.
  4. 不要投射bsearch. 不要将函数指针转换为不同的类型。
  5. for(int i; i <没有初始化i...
  6. if(!buff){检查是否未设置 buff。应该是if(buff){

  1. 我认为没有理由将指针传递给 a char *,只需传递密钥本身。
  2. 来自的回调bsearch将键与数组中的元素进行比较。

int myCompareFruits(const void *s1, const void *s2) {
    const char *key = s1;
    const fruit_shelf_t *b = s2;
    printf("%s %s\n", key, b->fruit_name);
    return strcmp(key, b->fruit_name);
}

int binary_search(food_aisle_t* food_aisle, char *key){
    fruit_shelf_t *buff = bsearch(key, food_aisle->fruits,
        MAX_ITEM_SIZE, sizeof(fruit_shelf_t), myCompareFruits);
    if (buff) {
于 2022-01-03T00:05:20.977 回答