Односвязный список студентов в C, не может получить доступ ко всем полям из узла, созданного в другой функции - PullRequest
1 голос
/ 06 марта 2019

Я пытаюсь выполнить упражнение для класса, в котором мы учим C. Мы должны создать односвязный список из struct STUDENT_RECORD s. Каждая запись студента предназначена для того, чтобы быть узлом в односвязном списке. Вот что это за определение:

struct STUDENT_RECORD{
     char *name;
     float gpa;
     int age;
     struct STUDENT_RECORD *next;
 };

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

Одним из полей этого struct является name. Поскольку мы получаем данные от пользователя из цикла, который перезаписывает переменную name, в которой хранится имя, введенное пользователем, мне придется скопировать каждое имя, чтобы оно было сохранено в списке.

Вот что у меня есть:

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include "student.h"

struct STUDENT_RECORD* addNode(char* name, int anAge, float aGPA){
//this is the function that creates the new STUDENT_RECORD and returns a reference to it

//copy the input name in another string
     char nameCopy [strlen(name)+1];
     int i = 0;
     while(name[i] != '\0'){
         nameCopy[i] = name[i];
         i++;
     }
     nameCopy[strlen(name)] = '\0';

//create a new node/STUDENT_RECORD
     struct STUDENT_RECORD *ttemp = (struct STUDENT_RECORD *)malloc    (sizeof(struct STUDENT_RECORD));

//fill the new STUDENT_RECORD with input arguments
     ttemp->name = nameCopy;
     ttemp->age = anAge;
     ttemp->gpa = aGPA;
     ttemp->next = NULL;

     puts("Test to see if the data is copied right:");
     printf("%s, %d, %f\n", ttemp->name, ttemp->age, ttemp->gpa);
     return ttemp;
}


int main() {
     struct STUDENT_RECORD *head = {"dummy", 0, 0, NULL};
     char selection='Y', aName[50], garbage;
     int anAge;
     float aGPA;
     while (toupper(selection) == 'Y') {

     // prompt the user for aName[], anAge, and aGPA
         puts("Enter the student's name (up to 49 characters), age, and GPA: ");
         scanf("%s", aName);
         scanf("%d", &anAge);
         scanf("%f", &aGPA);


     struct STUDENT_RECORD *temp = addNode(aName, anAge, aGPA); 
     printf("Student created: %s, %d, %f\n", temp->name, temp-> age,temp-> gpa); //prints everything but the student name

     printf("Continue? (Y/N): ");
     //clear the buffer of the newline from the previous entry newline
     garbage = getc(stdin);
     scanf("%c", &selection);
     }

//printNodes(head);
 }

Теперь, одна из многих проблем, с которыми я столкнулся, заключается в том, что указатель *temp не может видеть поле name STUDENT_RECORD. Я могу просматривать все остальные с основного, без проблем. то есть, когда я пытаюсь напечатать все поля возвращенного STUDENT_RECORD, я получаю их все, кроме имени. Я не понимаю, почему это не работает: насколько я понимаю, после вызова функции addNode мне возвращается ссылка на узел, и я должен иметь возможность печатать все его поля из основного, нет

Я уверен, что есть и другие проблемы, но сейчас было бы хорошим началом, по крайней мере, иметь возможность доступа ко всем полям данного STUDENT_RECORD из основной функции.

Спасибо !!

1 Ответ

3 голосов
/ 06 марта 2019

Вы не сохранили копию имени.Вы сделали локальную копию, а затем сохранили указатель на нее, который стал недействительным в тот момент, когда ваша функция вернулась.

Вот почему ваш тест внутри функции не показал никаких проблем.После того, как функция вернулась, использование этого указателя привело к неопределенному поведению.

Выделите память для вашей строки с помощью malloc:

char *nameCopy = malloc(strlen(name)+1);
if (nameCopy) strcpy(nameCopy, name);

Не забудьте free эту память позже, когда вы обойдетечтобы удалить ваши узлы.

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