【问题标题】:Why is my loop creating extra linked list nodes?为什么我的循环会创建额外的链表节点?
【发布时间】:2019-08-24 02:11:02
【问题描述】:

我正在使用链表。我想创建一个允许用户将节点添加到列表的循环。我的输出总是有两个额外的空白节点。我相信这与我使用输入函数获取输入和取消循环的方式有关,但我无法确定问题出在哪里。

我尝试了多种变体,包括以循环表达式终止和 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->空

提前致谢!

【问题讨论】:

  • 不要转换 malloc 的结果。不要在-&gt; 周围添加空格。
  • 您不应以_t 为后缀命名变量。它们保留用于特殊用途。在这里阅读stackoverflow.com/questions/231760/…
  • 我也不知道为什么要这样做,但请避免将名称 new 赋予变量。 newc++ 中的关键字。大多数阅读您的代码的程序员在第一次看到它时会有些困惑。
  • 您可能会发现Singly Linked List of Integers (example) 很有帮助。
  • if(c == 'n' || c =='N') 是多余的,因为c 在循环开始时不会是n(但你应该将它初始化为某个东西),它不会是下次循环时,while 子句将摆脱它。

标签: c while-loop linked-list getc


【解决方案1】:

每个循环,你都这样做:

  • new-&gt;val = user_input
  • new-&gt;next = new_node()
  • new = new-&gt;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 * 请求空间,这是指向您的数据结构的指针;你应该打电话给malloc(sizeof(node_t))malloc(sizeof(*temp))。您可能无意中覆盖了某些内容。

我假设第二个零来自您使用程序的方式:如果您按下:1enterenter2enterenter3enterenter、[nothing]、entern,然后scanf 将收到一个空字符串并评估为0

你应该检查scanf的返回值:它报告有多少字段匹配成功。

处理用户输入的更好方法可能是:

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;
    }
}

【讨论】:

  • 最好是node_t *temp = malloc (sizeof *temp); 使用取消引用的指针来设置类型大小,以消除所有出错的机会。
  • 好主意。编辑了答案。
猜你喜欢
  • 2013-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
  • 2013-07-23
  • 2021-07-18
相关资源
最近更新 更多