通过结构数组搜索的函数(C)
这是一个地址:通过结构数组搜索的函数(C),c,arrays,search,C,Arrays,Search,这是一个地址: struct Adress { char name[31], lastname[31], email[48]; }; 目标是在主函数中有一个地址簿,用户应该能够键入一个字符串,程序将列出地址簿中所有姓名或姓氏包含给定字符串的人。 例如,如果通讯簿包含“john”“doe”、“jane”“doey”和“george”“johnson”,并且用户键入“doe”,则输出为: 1. john doe johndoe@email.com 2. jane doey janedo
struct Adress {
char name[31], lastname[31], email[48];
};
目标是在主函数中有一个地址簿,用户应该能够键入一个字符串,程序将列出地址簿中所有姓名或姓氏包含给定字符串的人。
例如,如果通讯簿包含“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
以下是我的尝试:
在我的主函数的代码段中(这里不需要发布输入内容):
以下是搜索功能:
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循环中,搜索不是从以前找到的成员开始的,而是每次都从开始开始,因此每次都会继续查找相同的、最先找到的成员。您有一些问题要提
search()
,这是绝对不必要的,应该调用一次并存储它的返回值成员
指针永远不会指向第一个匹配项之后,因此始终会找到第一个匹配项,
导致无限循环成员
指针,但仍将元素数
传递给搜索函数。当您增加成员
指针时,其结果位置左侧至右侧的元素数量将减少与您增加成员
相同的数量((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()中
在这种方法中,在search()
函数中增加member
指针,以指向找到的元素,并添加一个计数器以反映已提前多少
search()
函数返回后,成员应再次增加1以指向下一个元素,并且number\u of_elements
应减少查找到的元素的搜索函数中的高级元素数+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);
}
}
希望能有帮助。祝你好运。为什么要调用搜索两次??一旦保存了结果,测试-1,如果没有,使用结果作为偏移量,而不是再次使用相同的参数调用相同的函数?而且您不需要在搜索
中计算索引
。指针数学可以帮你做到这一点<代码>索引=(i-数组)代码>应该足以获得正确的索引。嗯,没有这个除法,我如何获得索引?我知道事情可以优化一点,但首先我需要让它工作,并找出它为什么会进入无限循环。这是一段奇怪的代码。为什么不使用整数索引i
,它从0
迭代到数组的长度,并引用array[i].name
等?对于无限循环,在传递给函数之前,如何计算地址簿的size\u?同样,指针算法。它在这个代码中做了两次,都是错误的。你所做的事情不需要任何规模的部门。因此,函数中的循环仍然可以从0
迭代int i
到number\u of_elements-1
引用array[i]
。它会更干净,你的循环至少会正确终止,留下你来解决其他问题。如果我将它与地址簿-1的大小相比较,它仍然卡在一个无限循环中。@BaneBojanić你怎么知道它是一个无限循环?你使用调试器了吗?假设我有两个成员,他们的姓氏相同,名字不同。如果我搜索姓氏(或其一部分),程序将打印出无限行的I。第一个成员的名字第一个成员的姓氏,i从1到无穷大。@BaneBojanić为什么要调用搜索两次?非常感谢您的帮助。:)此行:*end=数组+地址簿的大小;数组+地址簿的大小可能超出地址簿数组?编辑:没关系,我在第二个函数中看到了调整。不幸的是,你的函数打印出包含第一个找到的成员的无限多行,就像我的函数一样…@BaneBojanić是的,我刚刚意识到这一点<代码>基准
未正确调整。现在应该可以了。这将教会我发布未经测试的代码。非常感谢。我想我应该发布整个代码,但这很难,因为我必须将所有变量翻译成英语,使其可读。。。
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;
}
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);
}
}