0

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

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

当前输出为:
>1->2->3->0->0->null

提前致谢!

4

1 回答 1

1

每个循环,你都这样做:

  • 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要求空间 for node_t *,这是指向您的数据结构的指针;你应该打电话malloc(sizeof(node_t))malloc(sizeof(*temp))。您可能会意外覆盖某些内容。

我会假设第二个零来自您使用程序的方式:如果您按:1, enter, enter, 2, enter, enter, 3, enter, enter, [nothing], enter, n, 那么scanf将收到一个空字符串并且评估为 as 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;
    }
}
于 2019-08-24T02:36:46.413 回答