Хорошая новость заключается в том, что вы на правильном пути. Плохая новость в том, что на вашем пути не хватает пары рельсов ...
Для начала, когда вы выделяете память с помощью malloc
,блок памяти зарезервирован, но все байты в блоке остаются неинициализированными .Попытка получить доступ к чему-либо в пределах неинициализированной области памяти Неопределенное поведение - с этого момента работа вашего кода больше не определяется - может показаться, что он работает, или SegFault, или что-то между ними.
У вас есть два варианта: (1) либо пройти по каждой структуре и явно инициализировать значения, либо (2) использовать calloc
, который будет распределять и инициализировать все байты в ноль, например,
#define MAXN 100 /* if you need a constrant #define 1 (or more) */
struct test {
char name[MAXN];
char num[MAXN];
};
...
int main() {
int index;
struct test *t;
char name[MAXN] = "";
t = calloc(MAXN, sizeof *t); /* use calloc, or initialize values */
if (t == NULL) { /* validate every allocation */
perror ("calloc-t");
return 1;
}
Не выделяйте t
снова в equalname
.Хотя это не перезаписывает ваш исходный адрес из-за того, что C использует передачу по значению, а t
является копией t
из main - это также ничего не делает для вас, согласитесь создать еще один неинициализированный блок памяти.Просто передайте t
из main
и используйте его, например,
int equalname (struct test *t, char *string)
{
int i;
printf("t[1].name == %s\n", t[1].name);
for (i = 0; i < MAXN; i++)
{ /* you must use strcmp to compare strings, not == */
if (strcmp (t[i].name, string) == 0)
{
printf ("t[i].name == name!\n");
return i;
break;
}
}
printf("WRONG");
return -1;
}
Далее, вы не можете сравнивать строки с ==
.Вы должны либо зацикливаться на каждом символе и сравнивать - или просто использовать strcmp
(это то, что было написано для этого), например,
if (strcmp (t[i].name, string) == 0)
{
printf ("t[i].name == name!\n");
return i;
break; /* break does nothing here */
}
Далее, вы должны validate каждое распределение и каждый пользовательский ввод - в противном случае вы приглашаете Неопределенное поведение .Если вам не удается проверить распределение и не подтвердить входные данные - вы не можете быть уверены, что фактически обрабатываете действительные данные в допустимой памяти в вашем коде.
Поместив их в целом, вы можете сделать что-то вроде следующего:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXN 100 /* if you need a constrant #define 1 (or more) */
struct test {
char name[MAXN];
char num[MAXN];
};
int equalname (struct test *t, char *string)
{
int i;
printf("t[1].name == %s\n", t[1].name);
for (i = 0; i < MAXN; i++)
{ /* you must use strcmp to compare strings, not == */
if (strcmp (t[i].name, string) == 0)
{
printf ("t[i].name == name!\n");
return i;
break;
}
}
printf("WRONG");
return -1; /* on error return a value that cannot be a valid index */
}
int main() {
int index;
struct test *t;
char name[MAXN] = "";
t = calloc(MAXN, sizeof *t); /* use calloc, or initialize values */
if (t == NULL) { /* validate every allocation */
perror ("calloc-t");
return 1;
}
printf ("Name: ");
if (scanf ("%s", name) != 1) { /* validate ALL user input */
fprintf (stderr, "error: invalid input - name.\n");
return 1;
}
strcpy (t[1].name, name);
printf ("t[1].name == %s\n", t[1].name);
index = equalname (t, name); /* save the return! */
if (index == -1) { /* validate the operation of your function */
fprintf (stderr, "string '%s' not found.\n", name);
return 1;
}
printf ("string found at index '%d'.\n", index);
return 0;
}
Пример использования / вывода
$ ./bin/struct_find_str
Name: Alfred
t[1].name == Alfred
t[1].name == Alfred
t[i].name == name!
string found at index '1'.
Дайте мне знать, если у вас есть дополнительные вопросы.