运行下面的代码后,我得到输出
名称:(空)|平均绩点:0.000000 |年份:(空)
链表没有正确实现吗?我目前正在使用 makefile 并引入一个包含名称、gpa 和senior/etc 的 test.data 文件。
奥利2.9新生
约翰3.2高级
朱莉2.2新生
乔1.8新生
玛丽3.8高级
苏3.4初级
简2.7高级
鲍勃2.8高级
弗雷德3.2新生
法案3.3初级
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "students.h"
Student *top = NULL;
Student *temp, *temp1, *temp2;
// Creates the entire linked list from the file.
// Should call readNext and push
// Returns head of the linked list
Student *buildStudentList()
{
Student *p;
p = readNext();
push(&top, p);
return top; //TODO: Change return
}
//Read a single line from standard input and return a student structure located on the heap
Student *readNext()
{
Student *s =(Student*) malloc(sizeof(Student));
scanf("%s", s -> name);
scanf("%f", &s -> gpa);
scanf("%s", s -> year);
s->next = NULL;
return s; //TODO: Change return
}
//Return a student structure stored on the heap
Student *makeStudent(char *name, float gpa, char *year)
{
Student *s =(Student*) malloc(sizeof(Student));
s -> name = name;
s -> gpa = gpa;
s -> year = year;
s -> next = NULL;
return s; //TODO: Change return
}
//insert a new student node at the head of the linked list
void push(Student **list, Student *student)
{
top = *list;
student -> next = top;
top = student;
}
//Insert a student node in the desired position on the linked list
void insert(Student *list, Student *s, int position)
{
int i;
top = list;
temp = top;
for(i = 1; i < position -1; i++)
{
temp = temp -> next;
}
if(temp == NULL)
{
//blank
}
else
{
s -> next = temp -> next;
temp -> next = s;
}
}
//Displays contents of a single student structure
void display(Student *s){
printf("NAME:%s | GPA: %f | YEAR:%s
", s -> name, s-> gpa, s -> year);
}
//Displays contents of the entire linked list
void displayAll(Student *list)
{
temp = list;
while(temp != NULL)
{
display(temp);
temp = temp -> next;
}
}
//Delete all data allocated on the heap before terminating program
void cleanUp(Student *list)
{
temp1 = list;
temp2 = temp1 -> next;
while(temp1 != NULL)
{
free(temp1);
temp1 = temp2;
}
if(temp2 != NULL)
{
temp2 = temp2 -> next;
}
}
//Main function tests your functions.
int main()
{
printf("Program Started
");
//Construct Linked List from Standard Input
Student *list = buildStudentList();
//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
");
exit(EXIT_SUCCESS);
}
最佳答案
由于您没有发布您的 struct
定义,我不得不猜测(例如)name
是否是 char *name;
或 (例如字符名称[100];
)。在代码中,它将它用作指针。
所以...
您的 readNext
和 makeStudent
没有为字符串(char *
指针)name
和年
,所以它们可能出现了段错误。
insert
在真正需要 Student **list
时采用 Student *list
。
IMO,您应该有一个单独的 List
类型以避免混淆(具有单个元素:Student *head;
)。因此,无论您在哪里有 Student *list
,都可以将其替换为 List *list
当你这样做时,当你指的是列表时,你不必传递 Student **
[双星] 指针。使用 list->head
比 *list
更容易且更具描述性。
此外,要保持一致。某些函数如果修改列表[他们必须],就会采用Student **list
。其他人使用 Student *list
,但它们也应该保持一致。
不需要各种全局范围的临时变量。这些应该是函数作用域并使用更具描述性的名称。
您的插入
有问题。如果找不到位置匹配,它将孤立尝试插入的节点(例如,在示例中插入位置 99)。通常是在尾部插入或返回错误代码。另外,由于您拥有的代码,[对我来说]并不完全清楚 position
意味着什么。它可能是“在第 N 个节点之前插入”或“在第 N 个节点之后插入”。
您不能在双引号字符串中插入文字换行符。因此,请使用 \n
转义序列(例如)printf("hello world\n");
此外,不带参数的函数应使用 void
(例如)而不是 int main()
,使用 int main (无效)
。
这是代码的清理版本,其中包含我上面提到的内容:
#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);
}
关于c - 代码运行时输出错误链接列表问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53713874/