为什么我的循环会创建额外的链表节点?
Why is my loop creating extra linked list nodes?
我正在使用链表。我想创建一个循环,允许用户将节点添加到列表中。我的输出总是有两个额外的空白节点。我相信这与我使用输入函数接受输入和取消循环的方式有关,但我无法确定问题出在哪里。
我已经尝试了多种变体,包括作为循环表达式终止以及在循环内终止 while(1)。
我希望我在 Windows 10 上使用 Ubuntu 没关系,但谁知道呢。
#include <stdio.h>
#include <stdlib.h>
#include <stdio_ext.h>
#include <stdbool.h>
typedef struct node {
int val;
struct node * next;
} node_t;
node_t * init_node();
void print_list(node_t * head);
int main(){
node_t * new = init_node();
node_t * head = new;
int c;
printf("\n\tAt any time Press 'N' to quit.\n");
do{
if(c == 'n' || c =='N') {
break;
}
//__fpurge(stdin);
printf("\n\tEnter a value for the new node: ");
scanf("\n%d", &new -> val);
new -> next = init_node();
new = new -> next;
} while(c = getc(stdin) != 'N' && c != 'n');
printf("\n\t");
print_list(head);
return 0;
}
node_t * init_node(){
node_t * temp = (node_t *) malloc( sizeof(node_t *) );
temp -> next = NULL;
return temp;
}
void print_list(node_t * head){
node_t * current = head;
printf("\n\t");
while(current != NULL){
printf("%d->",current -> val);
current = current -> next;
}
printf("null\n");
}
输入:1、2、3 ...
期望的输出是:
>
1->2->3->空
当前输出为:
>
1->2->3->0->0->空
提前致谢!
每个循环,你这样做:
new->val = user_input
new->next = new_node()
new = new->next
因此,每次,您都会在列表末尾添加一个新的、未初始化的节点。这恰好是您当前系统中的 0
,但不一定是。
最初您的列表包含:
[?] -> null
那个?表示未初始化的数据,正好是0,[]表示new
指向的节点
当您在第一个循环中输入 1
时,您:
- 改变?成 1
- 使用未初始化的数据创建一个新的
next
节点
- 让
new
指向它
所以你的列表包含
1 -> [?] -> null
然后输入2得到:
1 -> 2 -> [?] -> null
最后,print_list
会这样执行:
[1] -> 2 -> ? -> null
Prints `1 ->`
1 -> [2] -> ? -> null
Prints `2 ->`
1 -> 2 -> [?] -> null
Prints `0 ->` // But could print anything.
1 -> 2 -> ? -> [null]
Breaks the loop and prints `null`
此外,您的 malloc
正在为 node_t *
请求 space,这是指向您的数据结构的指针;你应该打电话给 malloc(sizeof(node_t))
或 malloc(sizeof(*temp))
。您可能不小心覆盖了某些内容。
我假设第二个零来自您使用程序的方式:如果您按:1
、enter
、enter
、2
, enter
, enter
, 3
, enter
, enter
, [无], enter
, n
, 然后 scanf
将收到一个空字符串并且评估为 0
.
您应该检查 scanf
的 return 值:它报告了成功匹配的字段数。
处理用户输入的更好方法可能是:
while (1) {
char user_input[BUFSIZE];
fgets(user_input, BUFSIZE, stdin);
if (sscanf(user_input, "%d", node->val)) {
...
} else if (user_input[0] == 'n' || user_input[0] == 'N') {
break;
}
}
我正在使用链表。我想创建一个循环,允许用户将节点添加到列表中。我的输出总是有两个额外的空白节点。我相信这与我使用输入函数接受输入和取消循环的方式有关,但我无法确定问题出在哪里。
我已经尝试了多种变体,包括作为循环表达式终止以及在循环内终止 while(1)。
我希望我在 Windows 10 上使用 Ubuntu 没关系,但谁知道呢。
#include <stdio.h>
#include <stdlib.h>
#include <stdio_ext.h>
#include <stdbool.h>
typedef struct node {
int val;
struct node * next;
} node_t;
node_t * init_node();
void print_list(node_t * head);
int main(){
node_t * new = init_node();
node_t * head = new;
int c;
printf("\n\tAt any time Press 'N' to quit.\n");
do{
if(c == 'n' || c =='N') {
break;
}
//__fpurge(stdin);
printf("\n\tEnter a value for the new node: ");
scanf("\n%d", &new -> val);
new -> next = init_node();
new = new -> next;
} while(c = getc(stdin) != 'N' && c != 'n');
printf("\n\t");
print_list(head);
return 0;
}
node_t * init_node(){
node_t * temp = (node_t *) malloc( sizeof(node_t *) );
temp -> next = NULL;
return temp;
}
void print_list(node_t * head){
node_t * current = head;
printf("\n\t");
while(current != NULL){
printf("%d->",current -> val);
current = current -> next;
}
printf("null\n");
}
输入:1、2、3 ...
期望的输出是:
>
1->2->3->空
当前输出为:
>
1->2->3->0->0->空
提前致谢!
每个循环,你这样做:
new->val = user_input
new->next = new_node()
new = new->next
因此,每次,您都会在列表末尾添加一个新的、未初始化的节点。这恰好是您当前系统中的 0
,但不一定是。
最初您的列表包含:
[?] -> null
那个?表示未初始化的数据,正好是0,[]表示new
指向的节点
当您在第一个循环中输入 1
时,您:
- 改变?成 1
- 使用未初始化的数据创建一个新的
next
节点 - 让
new
指向它
所以你的列表包含
1 -> [?] -> null
然后输入2得到:
1 -> 2 -> [?] -> null
最后,print_list
会这样执行:
[1] -> 2 -> ? -> null
Prints `1 ->`
1 -> [2] -> ? -> null
Prints `2 ->`
1 -> 2 -> [?] -> null
Prints `0 ->` // But could print anything.
1 -> 2 -> ? -> [null]
Breaks the loop and prints `null`
此外,您的 malloc
正在为 node_t *
请求 space,这是指向您的数据结构的指针;你应该打电话给 malloc(sizeof(node_t))
或 malloc(sizeof(*temp))
。您可能不小心覆盖了某些内容。
我假设第二个零来自您使用程序的方式:如果您按:1
、enter
、enter
、2
, enter
, enter
, 3
, enter
, enter
, [无], enter
, n
, 然后 scanf
将收到一个空字符串并且评估为 0
.
您应该检查 scanf
的 return 值:它报告了成功匹配的字段数。
处理用户输入的更好方法可能是:
while (1) {
char user_input[BUFSIZE];
fgets(user_input, BUFSIZE, stdin);
if (sscanf(user_input, "%d", node->val)) {
...
} else if (user_input[0] == 'n' || user_input[0] == 'N') {
break;
}
}