arrays - (C) 使用 bsearch 在 struct 数组中按名称查找 struct
问题描述
我正在尝试实现函数 (1) 以在结构数组中按名称查找特定产品。p_array 是包含 n 个产品的结构数组,search_key 是指向具有搜索结构名称的字符串的指针 cmp 是指向我已实现的另一个函数 (2) 的指针。
/* (1) */
const Product* findProduct(const Product* p_array, const char* search_key, int (*cmp)(const void*, const void*))
{
return bsearch(&search_key, p_array, 100, sizeof(Product), cmp);
}
/* (2) */
int compareAlpha(const void* a, const void* b)
{
const struct Product *shop_a = a;
const struct Product *shop_b = b;
int ret = strcmp(shop_a->name,shop_b->name);
return ret;
}
我有以下问题:
- 我想不出办法找出 p_array 的长度
- 启动程序导致分段错误,我不知道为什么
我的主要功能是:
void printProducts(Product* array)
{
int i = 0;
while(array[i].name[0] != 0)
{
printf("product: %s\tprice: %f\t in stock: %d\n", array[i].name, array[i].price, array[i].in_stock);
i++;
}
}
int main()
{
Product array[6] = {
{"peanut butter", 1.2, 5},
{"cookies", 12.3, 23},
{"cereals", 3.2, 12},
{"bread", 2.7, 12},
{"butter", 4.2, 5},
{"\0", 0.0, 0}
};
qsort(array, 5, sizeof(Product), compareAlpha);
printf("sorted lexically:\n");
printProducts(array);
const Product* search = findProduct(array, "cookies", compareAlpha);
if(search)
{
printf("Found product:\n");
printf("%s\n", search->name);
}
qsort(array, 5, sizeof(Product), compareNum);
printf("sorted by in stock:\n");
printProducts(array);
return 0;
}
想要的输出是
sorted lexically:
product: bread price: 2.700000 in stock: 12
product: butter price: 4.200000 in stock: 5
product: cereals price: 3.200000 in stock: 12
product: cookies price: 12.300000 in stock: 23
product: peanut butter price: 1.200000 in stock: 5
Found product:
cookies
Product not found!
sorted by in stock:
product: cookies price: 12.300000 in stock: 23
product: bread price: 2.700000 in stock: 12
product: cereals price: 3.200000 in stock: 12
product: butter price: 4.200000 in stock: 5
product: peanut butter price: 1.200000 in stock: 5
解决方案
您的代码中有几个错误:
compareAlpha()
在您的函数中无法进行转换。你应该改为写const struct Product* shop_a = (const struct Product*)a;
- 在您的
printProducts()
函数中,您应该将array[i].name[0]
null 字符'\0'
而不是 0 进行比较,即while(array[i].name[0] != '\0')
array
在函数中传递参数printProducts()
,会生成警告。您将其声明array
为静态数组而不是指针(尽管它是固有实现的并且可以作为指针访问),这会产生警告。你应该像这样传递它void printProducts(Product array[])
。- 在
findProduct()
函数中,当您调用该bsearch()
函数时,您将参数传递给 search as&search_key
。您应该改为不通过&
. - 的返回类型
findProduct()
应该是void*
而不是const Product*
因为bsearch()
函数的返回类型是void*
。因此,在从函数获得返回值后findProduct()
,您需要将其类型转换为const Product*
. - 您在某些地方使用类型时没有使用
struct
关键字。Product
在 c++ 中,它是可选的,但在 C 中是强制性的。
- 我想不出办法找出 p_array 的长度
您可以像这样找到数组的大小,int size = sizeof(array) / sizeof(array[0]);
但不建议这样做,因为它取决于编译器。
- 启动程序导致分段错误,我不知道为什么
以下是已纠正所有上述错误/警告的完整工作代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Product{
char name[100];
double price;
int in_stock;
};
int compareAlpha(const void* a, const void* b)
{
const struct Product* shop_a = (const struct Product*)a;
const struct Product* shop_b = (const struct Product*)b;
int ret = strcmp(shop_a->name, shop_b->name);
return ret;
}
int compareNum(const void* a, const void* b)
{
const struct Product* shop_a = (const struct Product*)a;
const struct Product* shop_b = (const struct Product*)b;
int ret = shop_a->in_stock <= shop_b->in_stock;
return ret;
}
void* findProduct(struct Product p_array[], const char* search_key, int (*cmp)(const void*, const void*))
{
return bsearch(search_key, (void*)p_array, 5, sizeof(struct Product), cmp);
}
void printProducts(struct Product array[])
{
int i = 0;
while(array[i].name[0] != '\0')
{
printf("product: %s\tprice: %f\t in stock: %d\n", array[i].name, array[i].price, array[i].in_stock);
i++;
}
}
int main()
{
struct Product array[6] = {
{"peanut butter", 1.2, 5},
{"cookies", 12.3, 23},
{"cereals", 3.2, 12},
{"bread", 2.7, 12},
{"butter", 4.2, 5},
{"\0", 0.0, 0}
};
qsort(array, 5, sizeof(struct Product), compareAlpha);
printf("sorted lexically:\n");
printProducts(array);
const struct Product* search = (const struct Product*)findProduct(array, "cookies", compareAlpha);
if(search)
{
printf("Found product:\n");
printf("%s\n", search->name);
}else{
printf("Product not found!\n");
}
qsort(array, 5, sizeof(struct Product), compareNum);
printf("sorted by in stock:\n");
printProducts(array);
return 0;
}