c - 为什么我的链表是向后打印的?



我想打印来自文件的链表内容,如下所示:

1,Postit Notes,Sticky notes,3
2,Black pens,Gel pens with black ink,5
3,Blue pens, Gel pens with blue ink, 4
4, Red pens, Gel pens with red ink for grading, 3
5, Notecards,Ruled 3" by 5" notecards,2
7,Whiteout,For mistakes made when writting with ink,3

到目前为止,在我的程序中,我的输入被正确读取,并且我已经调试了该部分,所以我知道这不是问题。我在打印链表时遇到问题。

我尝试编写一个addRecord方法(如下所示),其中我为新节点分配内存,分配它所需的数据,并尝试添加它,添加链表的末尾。我还有一个打印链表内容的方法,如下所示:

static void *addRecord(List *list, int newID, char *newName, char *newSummary, int newCount) 
{
//Allocate memory for the node
Node *new = (Node *)malloc(sizeof(Node)); 
//Add in data
new->id = newID;
strcpy(new->name, newName);
strcpy(new->summary, newSummary);
new->count = newCount;
//Node gets data you added in
new->next = list->head;
list->head = new;
return EXIT_SUCCESS;
}
void print(List *list)
{
printf("LIST IN FORWARD ORDER:n");
//Create a temporary node to traverse the list
Node *temp = list->head;
//Traverse the entire list
while (temp != NULL) {
printf("Item ID: %dn", temp->id);
printf("Name: %sn", temp->name);
printf("Summary: %sn", temp->summary);
printf("Count: %dn", temp->count);
printf("-----n");
temp = temp->next;
}
}

以下是我的链表的设置方式:

//struct for each office item
struct NodeStruct {
int id;
char name[MAX_NAME];
char summary[MAX_SUM];
int count;
struct NodeStruct *next;
};

/** Structure for the whole list, including head and tail pointers. */
typedef struct {
/** Pointer to the first node on the list (or NULL ). */
Node *head;
} List;

我的预期输出应如下所示:

LIST IN FORWARD ORDER:
Item ID: 1
Name: Postit Notes
Summary: Sticky notes
Count: 3
-----
Item ID: 2
Name: Black pens
Summary: Gel pens with black ink
Count: 5
-----
Item ID: 3
Name: Blue pens
Summary: Gel pens with blue ink
Count: 4
-----
Item ID: 4
Name: Red pens
Summary: Gel pens with red ink for grading
Count: 3
-----
Item ID: 5
Name: Notecards
Summary: Ruled 3" by 5" notecards
Count: 2
-----
Item ID: 7
Name: Whiteout
Summary: For mistakes made when writting with ink
Count: 3
-----

但是,我的实际输出是:

LIST IN FORWARD ORDER:
Item ID: 7
Name: Whiteout
Summary: For mistakes made when writting with ink
Count: 3
-----
Item ID: 5
Name:  Notecards
Summary: Ruled 3" by 5" notecards
Count: 2
-----
Item ID: 4
Name:  Red pens
Summary:  Gel pens with red ink for grading
Count: 3
-----
Item ID: 3
Name: Blue pens
Summary:  Gel pens with blue ink
Count: 4
-----
Item ID: 2
Name: Black pens
Summary: Gel pens with black ink
Count: 5
-----
Item ID: 1
Name: Postit Notes
Summary: Sticky notes
Count: 3
-----

在我的打印方法中,当我尝试打印头节点的内容时,我从 ID 为 7 的项目获取数据/信息,而我应该获取 ID 为 1 的项目的信息。有人可以向我解释为什么我的列表是向后打印的吗?我试图追踪它,但我有点困惑。我已经尝试了其他方法来添加记录,但是当我尝试这样做时,我总是Segmentation Fault: 11

提前谢谢你!

编辑:

在Thomas Jager下面的评论之后,我对我的addRecord方法进行了以下修改:

static void *addRecord(List *list, int newID, char *newName, char *newSummary, int newCount) 
{
//Allocate memory for the node
Node *new = (Node *)malloc(sizeof(Node)); 
//Add in data
new->id = newID;
strcpy(new->name, newName);
strcpy(new->summary, newSummary);
new->count = newCount;
//Special case: If the first node is null, add the data here
if (list->head->next == NULL) {
list->head->next = new;
} else {
Node *temp = new; 
while (temp != NULL) {
new = new->next; 
}
}
return EXIT_SUCCESS;
}

但是,现在,我收到以下错误:

Segmentation fault: 11

我无法理解发生的分段错误,有人可以向我解释一下吗?

问题在于您添加到列表的方式。您总是在列表的开头而不是尾部添加。

解决此问题的一种方法是更改addRecord函数:

static void addRecord(List *list, int newID, char *newName, char *newSummary, int newCount) 
{
//Allocate memory for the node
Node *new = malloc(sizeof(Node));
//Add in data
new->id = newID;
strcpy(new->name, newName);
strcpy(new->summary, newSummary);
new->count = newCount;
//New node has no next, yet
new->next = NULL;
//Add new node to the end of the list
Node **next_p = &list->head;
while (*next_p)
next_p = &(*next_p)->next;
*next_p = new;
}

有很多方法可以添加到列表的尾部。我在这里选择的方式使用指向Node *的指针。这允许以相同的方式表示List中的headNode中的next

另一种方式稍微不那么优雅,但更具可读性。避免使用双指针可以像在编辑的问题中所做的那样完成,但修改为遍历列表的next

//Add new node to the end of the list
if (!list->head->next) {
list->head->next = new;
} else {
Node *temp = list->head->next; 
while (temp->next) {
temp = temp->next; 
}
temp->next = new;
}

这两种情况都需要初始list->headNULL,但鉴于您的打印,似乎已经如此。

我还更改了几件事。不应在 C 中强制转换malloc的返回值。此外,您的addRecord具有返回类型void *,并且您返回EXIT_SUCCESS。如果尝试返回成功值,void *可能不是执行此操作的正确方法。

相关内容

  • 没有找到相关文章

最新更新