在结构中的字符串数组中使用 bsearch 搜索目标字符串
Search for a target string using bsearch in an array of string in a struct
您好,我正在使用 bsearch 在结构的字符串数组中搜索目标字符串,return 字符串的索引。但是,到目前为止它总是 returning 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]);
return编辑:
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);
return编辑:
Found key = (null) at index = -319396745.
key found
// Try 3:
int index = (buff - food_aisle->fruits[0].fruit_name) / sizeof(food_aisle->fruits[0]);
return编辑:
Found key = (null) at index = 233548559.
key found
这里的 bsearch()
用法可能有什么问题?
- 您正在将
strcmp
传递给 bsearch
。 strcmp
接受 const char*
个参数,bsearch
期待带有 const void*
的函数。
- 您正在将
strcmp
传递给 bsearch
。它比较字符串,而不是 fruit_shelf_t
. 的元素
myStrCmp
仍然比较字符串,而不是 fruit_shelf_t
与 key
。
- 不要转换
bsearch
的结果。不要将函数指针转换为不同的类型。
for(int i; i <
未初始化 i
...
if(!buff){
检查是否未设置 buff。应该是 if(buff){
.
- 我认为没有理由将指针传递给
char *
,只需传递密钥本身即可。
- 来自
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) {
您好,我正在使用 bsearch 在结构的字符串数组中搜索目标字符串,return 字符串的索引。但是,到目前为止它总是 returning 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]);
return编辑:
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);
return编辑:
Found key = (null) at index = -319396745.
key found
// Try 3:
int index = (buff - food_aisle->fruits[0].fruit_name) / sizeof(food_aisle->fruits[0]);
return编辑:
Found key = (null) at index = 233548559.
key found
这里的 bsearch()
用法可能有什么问题?
- 您正在将
strcmp
传递给bsearch
。strcmp
接受const char*
个参数,bsearch
期待带有const void*
的函数。 - 您正在将
strcmp
传递给bsearch
。它比较字符串,而不是fruit_shelf_t
. 的元素
myStrCmp
仍然比较字符串,而不是fruit_shelf_t
与key
。- 不要转换
bsearch
的结果。不要将函数指针转换为不同的类型。 for(int i; i <
未初始化i
...if(!buff){
检查是否未设置 buff。应该是if(buff){
.
- 我认为没有理由将指针传递给
char *
,只需传递密钥本身即可。 - 来自
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) {