单链表C,打印
Singly linked list C, printing
我是开发初学者,所以我的老师给了我一个任务来完成,我需要在链表中输入几个字符串,然后在我输入 print 之后,它们需要按正确的顺序打印出来,从头到尾。
这是我得到的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char data;
struct Node *next;
}node;
char createlist(node *pointer, char data[100]) {
while (pointer->next != NULL) {
pointer = pointer->next;
}
pointer->next = (node*) malloc(sizeof(node));
pointer = pointer-> next;
pointer->data = *data;
pointer->next = NULL;
}
int main() {
node *first, *temp;
first = (node*) malloc(sizeof(node));
temp = first;
temp->next = NULL;
printf("Enter the lines\n");
while (1) {
char data[100];
gets(data);
createlist(first, data);
if (strcmp(data, "print") == 0)
printf("%s\n", first->data);
else if (strcmp(data, "quit") == 0)
return (0);
};
}
当我 运行 它时,我得到:
输入行:
asdfasdf
打印
(空)
任何帮助将不胜感激,因为这是我第一次使用链表。
在 createlist()
内,您正在迭代到列表的末尾。在那里,您将添加一个新节点并设置输入的新文本。通过这样做,您错过了您已经拥有第一个节点。因为您在 createlist()
的每次调用中都迭代到末尾,所以每次都会跳过第一个节点,因此它仍然没有文本并传递 NULL
.
为了不跳过第一个初始节点,你可以这样修改createlist()
:
char createlist(node *pointer, char data[100])
{
while (pointer->data != NULL && pointer->next != NULL)
{
pointer = pointer->next;
}
...
...
}
或者您可以不在一开始就创建第一个节点,而是在输入第一行文本之后才创建。
编辑:这里有两个额外的样式提示:
如果有人输入 120 个字符会怎样?该文本将超过您的 char[100]
数组,并将填充其他情况下使用的 RAM。这是缓冲区溢出。您可以尝试只获取前 100 个字符,获取 substring. Alternatively, use the length argument of fgets()
像#define MAX_BUFFER_LENGTH 100
一样为100创建一个常量,每次都使用它。
- 您应该正确格式化您的代码。
first->data
通过 malloc()
分配且未初始化,因此使用其值会调用 未定义的行为.
- 为了不特殊处理第一个元素,应该使用指向指针的指针让
createlist()
修改first
。
- 因为
createlist()
不会 return 任何东西,它的 return 值的类型应该是 void
.
- 我猜您想复制字符串而不是分配每个字符串的第一个字符。
- 要打印您输入的所有内容,必须编写代码。
- 你不应该使用
gets()
,它有不可避免的缓冲区溢出风险。
- 你应该
free()
你通过 malloc()
分配的任何东西。
改进代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
char *data;
struct Node *next;
} node;
void createlist(node **pointer, char data[100])
{
while (*pointer != NULL)
{
pointer = &(*pointer)->next;
}
*pointer = malloc(sizeof(node));
if (*pointer == NULL)
{
perror("malloc 1");
exit(1);
}
(*pointer)->data = malloc(strlen(data) + 1);
if ((*pointer)->data == NULL)
{
perror("malloc 2");
exit(1);
}
strcpy((*pointer)->data, data);
(*pointer)->next = NULL;
}
int main(void)
{
node *first = NULL;
printf("Enter the lines\n");
while (1)
{
char data[100], *lf;
if (fgets(data, sizeof(data), stdin) == NULL) strcpy(data, "quit");
if ((lf = strchr(data, '\n')) != NULL) *lf = '[=10=]'; /* remove newline character */
createlist(&first, data);
if (strcmp(data, "print") == 0)
{
node *elem = first;
while (elem != NULL)
{
printf("%s\n", elem -> data);
elem = elem->next;
}
}
else if (strcmp(data, "quit") == 0)
{
while (first != NULL)
{
node *next = first->next;
free(first->data);
free(first);
first = next;
}
return(0);
}
}
}
我是开发初学者,所以我的老师给了我一个任务来完成,我需要在链表中输入几个字符串,然后在我输入 print 之后,它们需要按正确的顺序打印出来,从头到尾。
这是我得到的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
char data;
struct Node *next;
}node;
char createlist(node *pointer, char data[100]) {
while (pointer->next != NULL) {
pointer = pointer->next;
}
pointer->next = (node*) malloc(sizeof(node));
pointer = pointer-> next;
pointer->data = *data;
pointer->next = NULL;
}
int main() {
node *first, *temp;
first = (node*) malloc(sizeof(node));
temp = first;
temp->next = NULL;
printf("Enter the lines\n");
while (1) {
char data[100];
gets(data);
createlist(first, data);
if (strcmp(data, "print") == 0)
printf("%s\n", first->data);
else if (strcmp(data, "quit") == 0)
return (0);
};
}
当我 运行 它时,我得到: 输入行: asdfasdf 打印 (空)
任何帮助将不胜感激,因为这是我第一次使用链表。
在 createlist()
内,您正在迭代到列表的末尾。在那里,您将添加一个新节点并设置输入的新文本。通过这样做,您错过了您已经拥有第一个节点。因为您在 createlist()
的每次调用中都迭代到末尾,所以每次都会跳过第一个节点,因此它仍然没有文本并传递 NULL
.
为了不跳过第一个初始节点,你可以这样修改createlist()
:
char createlist(node *pointer, char data[100])
{
while (pointer->data != NULL && pointer->next != NULL)
{
pointer = pointer->next;
}
...
...
}
或者您可以不在一开始就创建第一个节点,而是在输入第一行文本之后才创建。
编辑:这里有两个额外的样式提示:
如果有人输入 120 个字符会怎样?该文本将超过您的
char[100]
数组,并将填充其他情况下使用的 RAM。这是缓冲区溢出。您可以尝试只获取前 100 个字符,获取 substring. Alternatively, use the length argument offgets()
像
#define MAX_BUFFER_LENGTH 100
一样为100创建一个常量,每次都使用它。
- 您应该正确格式化您的代码。
first->data
通过malloc()
分配且未初始化,因此使用其值会调用 未定义的行为.- 为了不特殊处理第一个元素,应该使用指向指针的指针让
createlist()
修改first
。 - 因为
createlist()
不会 return 任何东西,它的 return 值的类型应该是void
. - 我猜您想复制字符串而不是分配每个字符串的第一个字符。
- 要打印您输入的所有内容,必须编写代码。
- 你不应该使用
gets()
,它有不可避免的缓冲区溢出风险。 - 你应该
free()
你通过malloc()
分配的任何东西。
改进代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
char *data;
struct Node *next;
} node;
void createlist(node **pointer, char data[100])
{
while (*pointer != NULL)
{
pointer = &(*pointer)->next;
}
*pointer = malloc(sizeof(node));
if (*pointer == NULL)
{
perror("malloc 1");
exit(1);
}
(*pointer)->data = malloc(strlen(data) + 1);
if ((*pointer)->data == NULL)
{
perror("malloc 2");
exit(1);
}
strcpy((*pointer)->data, data);
(*pointer)->next = NULL;
}
int main(void)
{
node *first = NULL;
printf("Enter the lines\n");
while (1)
{
char data[100], *lf;
if (fgets(data, sizeof(data), stdin) == NULL) strcpy(data, "quit");
if ((lf = strchr(data, '\n')) != NULL) *lf = '[=10=]'; /* remove newline character */
createlist(&first, data);
if (strcmp(data, "print") == 0)
{
node *elem = first;
while (elem != NULL)
{
printf("%s\n", elem -> data);
elem = elem->next;
}
}
else if (strcmp(data, "quit") == 0)
{
while (first != NULL)
{
node *next = first->next;
free(first->data);
free(first);
first = next;
}
return(0);
}
}
}