Поскольку вы не опубликовали свое определение struct
, мне пришлось угадывать, было ли (например) name
char *name;
или (например, char name[100];
).В коде он использовал его как указатель.
Итак ...
Ваши readNext
и makeStudent
не выделяют место для строк (char *
указатели) name
и year
, так что они, вероятно, segfaulting.
insert
берет Student *list
, когда это действительно необходимо Student **list
.
IMO, у вас должно быть отдельное List
тип, чтобы избежать путаницы (который имеет один элемент: Student *head;
).Поэтому, где бы у вас не было Student *list
, вы заменяете его на List *list
Когда вы делаете это, вам не нужно передавать указатель Student **
[двойная звезда], когда вы имеете в виду список.Использование list->head
намного проще и более наглядно, чем *list
.
Кроме того, будьте последовательны.Некоторые функции принимают Student **list
, если они изменяют список [они имеют to].Другие используют Student *list
, но они также должны быть согласованными.
Нет необходимости в различных глобальных временных переменных области видимости.Они должны иметь функциональную область и использовать более описательные имена.
У вашего insert
есть проблемы.Это будет сирота узел, который он пытается вставить, если найдено нет совпадения позиции (например, вставка в позицию 99 в вашем примере).Обычно это вставить хвост или вернуть код ошибки.Кроме того, было не совсем понятно, что position
означало [для меня] из-за кода, который вы имели.Это мог быть «вставить до» или «вставить после» N-го узла.
Вы не можете вставить буквальный символ новой строки в строке в двойных кавычках.Таким образом, используйте escape-последовательность \n
(например) printf("hello world\n");
Кроме того, функции, которые принимают no аргументов, должны использовать void
(например) вместо int main()
, используйте int main(void)
.
Вот исправленная версия вашего кода, включающая то, что я упомянул выше:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
//#include "students.h"
typedef struct student Student;
struct student {
Student *next;
float gpa;
char *name;
char *year;
};
typedef struct list {
Student *head;
} List;
//insert a new student node at the head of the linked list
void
push(List *list, Student *student)
{
student->next = list->head;
list->head = student;
}
//Return a student structure stored on the heap
Student *
makeStudent(char *name, float gpa, char *year)
{
Student *s = (Student *) malloc(sizeof(Student));
s->name = strdup(name);
s->gpa = gpa;
s->year = strdup(year);
s->next = NULL;
return s;
}
//Read a single line from standard input and return a student structure located on the heap
Student *
readNext(void)
{
char name[1000];
float gpa;
char year[1000];
Student *s = NULL;
int count = scanf("%s %f %s",name,&gpa,year);
if (count == 3) {
printf("readNext: name='%s' gpa=%g year='%s'\n",name,gpa,year);
s = makeStudent(name,gpa,year);
}
return s;
}
// Creates the entire linked list from the file.
// Should call readNext and push
// Returns head of the linked list
List *
buildStudentList(List *list)
{
Student *p;
while (1) {
p = readNext();
if (p == NULL)
break;
push(list, p);
}
return list;
}
//Insert a student node in the desired position on the linked list
int
insert(List *list, Student *s, int position)
{
Student *cur;
Student *prev;
int i;
int goflg;
//position -= 1;
#if 0
i = 1; // insert before Nth position
#else
i = 0; // insert after Nth position
#endif
prev = NULL;
for (cur = list->head; (cur != NULL) && (i < position);
++i, cur = cur->next) {
prev = cur;
}
// this may not be needed -- usual is to insert at tail if position is not
// found -- this will orphan the node to be inserted
#if 0
goflg = (i == position);
#else
goflg = 1;
#endif
if (goflg) {
s->next = cur;
if (prev != NULL)
prev->next = s;
else
list->head = s;
}
return goflg;
}
//Displays contents of a single student structure
void
display(Student *s)
{
printf("NAME:%s | GPA: %f | YEAR:%s\n", s->name, s->gpa, s->year);
}
//Displays contents of the entire linked list
void
displayAll(List *list)
{
Student *temp = list->head;
while (temp != NULL) {
display(temp);
temp = temp->next;
}
}
//Delete all data allocated on the heap before terminating program
void
cleanUp(List *list)
{
Student *cur;
Student *next;
for (cur = list->head; cur != NULL; cur = next) {
next = cur->next;
free(cur->name);
free(cur->year);
free(cur);
}
list->head = NULL;
}
//Main function tests your functions.
int
main(void)
{
List top = { NULL };
List *list;
printf("Program Started\n");
//Construct Linked List from Standard Input
list = buildStudentList(&top);
//Insert a new student in desired position
Student *s = makeStudent("Max", 3.0, "senior");
insert(list, s, 3);
//Display entire linked list
displayAll(list);
//Free all heap memory
cleanUp(list);
printf("Program Successful Exit\n");
exit(EXIT_SUCCESS);
}