这是一个地址:
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循环中,搜索不会从先前找到的成员继续进行,而是每次从开头开始,因此每次都会找到相同的,首先找到的成员。
答案 0 :(得分:1)
你有几个问题需要提及
你在主循环中调用search()
两次是绝对不必要的,你应该调用它一次并存储它的返回值。
你的member
指针,在第一场比赛后永远不会指向,所以总会找到第一场比赛,
导致无限循环。
您增加member
指针并仍将number_of_elements
传递给搜索功能。当您增加member
指针时,其结果位置左侧的元素数量会减少与您增加member
相同的数字。
此表达式未提供您认为的值
((i - array)/(sizeof (struct Adress)));
因为您正在计算两个指针i
和array
之间的距离,然后将其除以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"
。
这是能够满足你需要的代码
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);
}
}
希望它有所帮助。祝你好运。