搜索结构数组的函数(C)

时间:2015-01-10 12:48:22

标签: c arrays search

这是一个地址:

struct Adress {
    char name[31], lastname[31], email[48];
};

目标是在main函数中有一个地址簿,用户应该能够键入一个字符串,程序会列出地址簿中名字或姓氏包含给定内容的所有人串。 例如,如果地址簿包含“john”“doe”,“jane”“doey”和“george”“johnson”,并且用户输入“doe”,则输出为:

 1. john doe johndoe@email.com
 2. jane doey janedoey@email.com

这部分主要功能应该使用一个功能

int search(struct Adress array[], int size_of_the_addressbook, char* string_to_search)

返回第一个找到的地址的索引,如果没有找到地址则返回-1。

这是我的尝试:

在我的main函数的片段中(这里不需要发布输入内容):

    struct Adress adressbook[1000], *member;
    int i = 0;
    member = adressbook;

    if (search(member, number_of_elements, string_to_seach)) == -1)
                printf("No person found.\n");

    else while((search(member, number_of_elements, string_to_seach)) != -1)
            {
                member = adressbook + search(member, number_of_elements, string_to_seach);
                ++i;


                printf("%d. %s %s - %s\n", i, (*member).name, (*member).lastname, (*member).email);
                ++member;
            }

这是搜索功能:

int search(struct Adress array[], int size_of_the_addressbook, char* string_to_search)
{
    int j, index;
    struct Adress *i;
    i = array;

    while (strstr((*i).name, string_to_search) == 0 && strstr((*i).lastname, string_to_search) == 0)
    {
        index = ((i - array)/(sizeof (struct Adress)));
        if (index == size_of_the_addressbook)   return -1;
        ++i;
    }
    index = ((i - array)/(sizeof (struct Adresa)));
    return index;
}

但是,当地址簿中有多个成员时,这个程序几乎无论如何都会陷入无限循环。我怀疑在while循环中,搜索不会从先前找到的成员继续进行,而是每次从开头开始,因此每次都会找到相同的,首先找到的成员。

2 个答案:

答案 0 :(得分:1)

你有几个问题需要提及

  1. 你在主循环中调用search()两次是绝对不必要的,你应该调用它一次并存储它的返回值。

  2. 你的member指针,在第一场比赛后永远不会指向,所以总会找到第一场比赛, 导致无限循环。

  3. 您增加member指针并仍将number_of_elements传递给搜索功能。当您增加member指针时,其结果位置左侧的元素数量会减少与您增加member相同的数字。

  4. 此表达式未提供您认为的值

    ((i - array)/(sizeof (struct Adress)));
    

    因为您正在计算两个指针iarray之间的距离,然后将其除以sizeof(struct Address) 110,并且作为另一个答案提到,值自动缩放,所以

    ((i - array)/(sizeof (struct Adress))); -> i - array;
    

    看看我的意思你可以尝试打印这个值

    printf("\t%d\n", ((void*)member - (void*)adressbook));
    printf("\t%d\n", ((void*)member - (void*)adressbook) / sizeof(*member));
    printf("\t%d\n", member - adressbook);
    

    注意:如果您的操作系统是64位,请将格式说明符更改为"%ld"

  5. 这是能够满足你需要的代码

    int search(struct Adress **array, int size_of_the_addressbook, char* string_to_search)
    {
        int            index;
        struct Adress *pointer;
    
        if ((size_of_the_addressbook == 0) || (array == NULL) || (*array == NULL))
            return -1;
    
        pointer = *array;
        index   = 0;
        while (strstr(pointer->name, string_to_search) == 0 && 
                   strstr(pointer->lastname, string_to_search) == 0)
        {
            /* check that we are not at the end of the array. */
            if (++index == size_of_the_addressbook)
                return -1;
            /* not found yet, increment both arrays */
            (*array)++;
    
            pointer = *array;
        }
    
        return index;
    }
    

    并在main()

    int index;
    int foundIndex;
    
    index = 1;
    while ((foundIndex = search(&member, number_of_elements, string_to_seach)) != -1)
    {
        printf("%d. %s %s - %s\n", index, member->name, member->lastname, member->email);
    
        index              += 1 + foundIndex;
        number_of_elements -= 1 + foundIndex;
    
        ++member;
    }
    

    在这种方法中,member指针在search()函数内增加以指向找到的元素,添加一个计数器以反映已提升的数量。

    search()函数返回后,成员应再次增加1指向下一个元素,number_of_elements应减少搜索函数中前进的元素数+ 1找到了元素。

    另外,保留一个在每次迭代时更新的变量,该变量为您提供数组中元素的实际index

答案 1 :(得分:1)

您的搜索实际上从未返回-1,并且您对该搜索的调用因此没有退出条件。此外,您应该将下一次搜索的每个起点调整为超出最后一个发现点。

我几乎可以肯定这是你尝试做的事情。我没有对此进行测试(没有数据可以执行此操作,也没有关于调用此功能的任何信息),但我希望这一点很明显:

int search(const struct Adress array[],
           int size_of_the_addressbook,
           const char* string_to_search)
{
    const struct Adress *end = array + size_of_the_addressbook;
    const struct Adress *i = array;

    for (; i != end; ++i)
    {
        if (strstr(i->name, string_to_search) != NULL ||
            strstr(i->lastname, string_to_search) != NULL)
            break;
    }

    return i == end ? -1 : (int)(i - array);
}

void do_search(const struct Adress *array,
               int number_of_elements,
               const char *string_to_search)
{
    int i = search(array, number_of_elements, string_to_search), base=0;
    if (i == -1)
    {
        printf("No person found.\n");
        return;
    }

    while (i != -1)
    {
        base += i;
        printf("%d. %s %s - %s\n", base,
               array[base].name,
               array[base].lastname,
               array[base].email);

        base += 1;

        // note adjustment of starting point using pointer arithmetic.
        i = search(array + base,
                   number_of_elements - base,
                   string_to_search);
    }
}

希望它有所帮助。祝你好运。