微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

(C) 用 bsearch 在 struct 数组中按名称查找 struct

如何解决(C) 用 bsearch 在 struct 数组中按名称查找 struct

我正在尝试实现函数 (1),以便在 struct 数组中按名称查找特定产品。 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;
}

我有以下问题:

  1. 我想不出办法找出 p_array 的长度
  2. 启动程序导致分段错误,我不知道为什么

我的主要功能是:

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,{"butter",4.2,{"\0",0.0,0}
    };

    qsort(array,5,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,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

解决方法

您的代码中有几个错误:

  1. 无法在您的 compareAlpha() 函数中进行转换。你应该写const struct Product* shop_a = (const struct Product*)a;
  2. 在您的 printProducts() 函数中,您应该将 array[i].name[0] 与空字符 '\0' 进行比较,而不是 0,即 while(array[i].name[0] != '\0')
  3. array 函数中传递参数 printProducts() 会生成警告。您将 array 声明为静态数组而不是指针(尽管它是固有实现的并且可以作为指针访问),这会生成警告。你应该像这样传递它 void printProducts(Product array[])
  4. findProduct() 函数中,当您调用 bsearch() 函数时,您将要搜索的参数作为 &search_key 传递。您应该在没有 & 的情况下传递它。
  5. findProduct() 的返回类型应该是 void* 而不是 const Product*,因为 bsearch() 函数的返回类型是 void*。所以,在你得到一个返回值之后 findProduct() 函数,您需要将其类型转换为 const Product*
  6. 您在某些地方使用 struct 类型时没有使用 Product 关键字。在 C++ 中,它是可选的,但在 C 中它是强制性的。

  1. 我想不出办法找出 p_array 的长度

您可以像这样找到数组的大小 int size = sizeof(array) / sizeof(array[0]); 虽然不推荐这样做,因为它依赖于编译器。


  1. 启动程序导致分段错误,我不知道为什么

以下是修正了所有上述错误/警告的完整代码。

#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,{"butter",4.2,{"\0",0.0,0}
    };

    qsort(array,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,compareNum);
    printf("sorted by in stock:\n");
    printProducts(array);

    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。