【问题标题】:how to read multiple lines from stdin and store it in linked list如何从标准输入读取多行并将其存储在链表中
【发布时间】:2019-06-04 10:56:14
【问题描述】:

我正在尝试编写一个程序,从用户(来自 STDIN)获取行并将它们存储在链表中。

现在我只得到一行并终止程序。 如何更改代码以继续从标准输入获取行?

另外,如果有人能告诉我我是否正在分配和释放内存,那将非常有帮助。

谢谢。

#include <stdio.h>
#include <stdlib.h>

int BUFF_SIZE = 128;

struct Node {
    char* data;
    struct Node* next;
};

struct Node* head = NULL;
struct Node* tail = NULL;

void free_list(struct Node* head)
{
    if (head != NULL)
    {
        free_list(head->next);
        free(head);
    }
}

int main()
{
    int curr_size = 0;

    char* pStr = malloc(BUFF_SIZE);
    curr_size = BUFF_SIZE;

    printf("%s", "please print multiple lines\n");
    if (pStr != NULL)
    {
        char c;
        int i = 0;

        while ((c = getchar()) != '\n' && c != EOF)
        {
            pStr[i++] = c;

            if (i == curr_size)
            {
                curr_size = i + BUFF_SIZE;
                pStr = realloc(pStr, curr_size);
                if (pStr == NULL) return;
            }
        }
        pStr[i] = '\0';

        struct Node* new_node = malloc(sizeof(struct Node*));
        char* new_data = malloc(sizeof(pStr));
        new_data = pStr;
        new_node->data = new_data;

        if (head == NULL)
        {
            head = new_node;
            tail = new_node;
        }

        else
        {
            tail->next = new_node;
        }
    }

    free_list(head);
}

【问题讨论】:

    标签: c linked-list


    【解决方案1】:

    几个问题:

    1. 截至目前,您将在收到\n 后终止阅读。

      if (pStr == NULL) return; //error
      
      int c;
      int i = 0;
      
      while ((c = getchar()) != EOF)
      {
         /*New word, insert into linked list*/
         if (c == '\n'){
             pStr[i] = '\0';
      
             struct Node* new_node = malloc(sizeof(*new_node));
             char* new_data = malloc(i+1);
             strcpy(new_data, pStr);
             new_node->data = new_data;
      
             if (head == NULL)
             {
                  head = new_node;
                  tail = new_node;
             }
             else
             {
                  tail->next = new_node;
                  tail = new_node;
             }
             i = 0; //Reset the index
         }
         else {
      
             pStr[i++] = c;
             if (i == curr_size)
             {
                 curr_size = i + BUFF_SIZE;
                 pStr = realloc(pStr, curr_size);
                 if (pStr == NULL) return;
             }
         }
      }
      
    2. 内存泄漏和节点data 将始终指向pStr 的最新内容。

      char* new_data = malloc(sizeof(pStr)); 
      new_data = pStr;   //Memory leak here
      new_node->data = new_data;
      

      改成

      char* new_data = malloc(i+1);
      strcpy(new_data, pStr);
      new_node->data = new_data;
      

      sizeof(pStr) 是指针的大小而不是字符串的长度。

    3. 每个节点插入列表后,您需要更新tail

       else
       {
           tail->next = new_node;
       }
      

       else
      {
          tail->next = new_node;
          tail = new_node;
       }
      

    【讨论】:

    • 哇,谢谢!这很有帮助。在改变了你所说的之后,我尝试插入几行并在最后打印头部和尾部 - 它们具有相同的数据。你知道为什么会这样吗?
    • 对不起,我是新来的,我该怎么办?
    • @beginnerCoder 在答案旁边的投票计数器下是一个复选标记。点击它。它应该变成绿色。仅供参考,此代码仍然存在问题。 c 应该是 int,而不是 char
    • @beginnerCoder 因为这就是getchar() 返回的内容,而且这很重要,尤其是在与EOF(您正在做的事情)进行比较时。
    • struct Node* new_node = malloc(sizeof(struct Node*));(从原始来源复制)是错误的。必须是 sizeof(struct Node)sizeof *new_node
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多