указатель на связанный список, вход scanf

Я пытаюсь ввести несколько раз указатель char в связанном списке, используя scanf. но каждый раз, когда я ввожу новый ввод, name изменяется во всех полях.

вот мой связанный список:

struct node {
struct node *next;
int level;
char *name;
};

вот моя основная функция:

struct node *root = NULL;
while (1) {
    char arrays[12];
    char *n;
    n = arrays;
    int i = NULL;
    printf("Enter level: ");
    scanf("%i", &i);
    printf("\nEnter name: ");
    scanf("%s", arrays);
    insert(&root, i, n, compare);
    display(root);
    }

функция вставки:

void insert(struct node **head, const int level, char *name, int(*cmp)(struct node *l, struct node *r))
{
    struct node *new;
    new = malloc(sizeof *new);
    new->level = level;
    new->name = name;

    /* Find the insertion point */
    for (; *head != NULL; head = &(*head)->next)
    {
        if ((*head)->level > level || (*head)->level == level && cmp(*head, new) > 0) { break; }
    }
    new->next = *head;
    *head = new;
}

в основном, если я ввожу:

input:        |   expected output:    |    actual output:
1     smith   |   1     john          |    1     alice
1     john    |   1     smith         |    1     alice
3     malek   |   2     alice         |    2     alice
2     alice   |   3     malek         |    3     alice

Примечание: функции работают должным образом, когда я ввожу данные вручную без scanf, например:

insert(&root, 1, "Abbas", compare);
insert(&root, 1, "Calbass", compare);

person Poorya    schedule 16.09.2016    source источник
comment
Простите за вопрос, но я не вижу возможности, чтобы бесконечный цикл в вашем методе main() когда-либо закончился. Также вы должны показать нам код функции insert.   -  person Tim Biegeleisen    schedule 16.09.2016
comment
Предоставьте код для функций вставки и отображения....   -  person Rupsingh    schedule 16.09.2016
comment
@TimBiegeleisen, вы правы, но бесконечный цикл был только для целей отладки.   -  person Poorya    schedule 16.09.2016
comment
scanf("%s", arrays); это ужасный поступок. По крайней мере, измените его на scanf("%11s", arrays);. В идеале вы хотите построить строку формата на основе sizeof arrays   -  person Happy Green Kid Naps    schedule 16.09.2016


Ответы (2)


Эта строка:

new->name = name;

просто измените значение указателя - он не копирует строку. Таким образом, все элементы в связанном списке будут указывать на arrays. Таким образом, изменение содержимого arrays создаст впечатление, что все элементы в списке были изменены (но это не так).

Вам, вероятно, нужно:

strcpy(новое->имя, имя);

а затем вам нужно malloc памяти для строки.

Что-то типа:

new = malloc(sizeof *new);
new->level = level;
new->name = malloc(12 * sizeof(char));  // Memory for the string
strcpy(new->name, name);                // Copy the input string

КСТАТИ:

Изменять

    insert(&root, i, n, compare);

to

    insert(&root, i, arrays, compare);

и удалите переменную n. Функциональность та же, но кодер легче читать и понимать.

person 4386427    schedule 16.09.2016

Похоже, вы вставляете указатель на arrays в список. Когда вы пишете:

insert(&root, 1, "Abbas", compare);

это работает, потому что ничто не изменяет строковый литерал «Abbas», но содержимое arrays перезаписывается каждый раз, когда выполняется scanf("%s", arrays);. Рассмотрите возможность изменения имени char* на имя char[12] и чтения ввода напрямую в узел.

person DDMC    schedule 16.09.2016