Язык C получает структуру в другой функции - PullRequest
0 голосов
/ 10 июня 2018

, когда я пытаюсь прочитать значение t[1].name внутри функции equalname, это не сработает.Как я могу отправить это значение в другую функцию?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

struct test {
    char name[100];
    char num[100];
};

int equalname(struct test *t, char string[100]) {
    int i;
    t = malloc(sizeof(struct test)*100);
    printf("t[1].name == %s\n", t[1].name); //prints garbage(t[1].name != name)
    for (i = 0; i < 100; i++) //also, is this even right?
    {
        if (t[i].name == string) //should I use 2 for's and set t[i].name[j] == string[j]?
        {
            printf("t[i].name == name!");
            return i;
            break;
        }
    }
    printf("WRONG");
    return 0;
}

int main() {
    struct test *t;
    t = malloc(sizeof(struct test)*100);
    char name[100];
    printf("Name:\n");
    scanf("%s", name);
    strcpy(t[1].name, name);
    printf("t[1].name == %s\n", t[1].name); //this works (t[1].name == name)
    equalname(t[1].name, name);
}

1 Ответ

0 голосов
/ 10 июня 2018

Хорошая новость заключается в том, что вы на правильном пути. Плохая новость в том, что на вашем пути не хватает пары рельсов ...

Для начала, когда вы выделяете память с помощью 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'.

Дайте мне знать, если у вас есть дополнительные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...