从 C 文件创建动态分配的字符串

标签 c tree

我在为树中的节点动态分配字符串时遇到了一些问题。我在下面包含了我的节点结构以供引用。

struct node
{
    char *string;
    struct node *left;
    struct node *right;
};
typedef struct node node;

我应该从文本文件中读取单词,然后将这些单词存储到树中。我能够毫无问题地存储已定义的 char 数组,例如 char string[20],但不能存储应该动态分配的字符串。

我只会发布我用来读取文件并尝试创建动态分配数组的代码。我已经创建了文件指针并检查它不是 NULL。每次我尝试运行该程序时,它都会崩溃,我是否需要尝试逐个字符地阅读单词?

//IN MAIN
node *p, *root ;
int i;
int u;

root = NULL;
char input[100];

while(fscanf(fp, "%s", &input) != EOF)
{
    //Create the node to insert into the tree
    p = (node *)malloc(sizeof(node));
    p->left = p->right = NULL;

    int p = strlen(input); //get the length of the read string
    char *temp = (char*) malloc(sizeof(char)*p); 
    //malloc a dynamic string of only the length needed

    strcpy(local, input);
    strcpy(p->word,local);

    insert(&root, p);
}

完全清楚,我只需要有关我的代码逻辑的建议,并且只希望有人帮助我指明正确的方向。

最佳答案

您正在通过

调用许多未定义的行为
  • 将指向具有错误类型的对象的指针传递给 scanf()。即在 fscanf(ifp, "%s", &input) 中,char(*)[100] 被传递到预期 char* 的地方
  • strcpy(local, input);
  • 中存储终止空字符时访问超出范围的已分配缓冲区
  • 使用通过 malloc() 分配的缓冲区值,但未在 strcpy(curr->word,local);
  • 中初始化

你的代码应该是这样的:

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

typedef struct node_t {
    struct node_t* left, *right;
    int count;
    char* word;
} node;
void insert(node ** tree, node * item);

int main(void) {
    FILE* ifp = stdin;

    node * curr, * root;
    int i;
    int u;

    root = NULL;
    char input[100];

    /* you should specify the maximum length to read in order to avoid buffer overrun */
    while(fscanf(ifp, "%99s", input) != EOF)
    {
        //Create the node to insert into the tree
        curr = malloc(sizeof(node));
        if(curr == NULL) /* add error check */
        {
            perror("malloc 1");
            return 1;
        }
        curr->left = curr->right = NULL;
        curr->count = 1;

        int p = strlen(input); //get the length of the read string
        char *local = malloc(sizeof(char)*(p + 1)); /* make room for terminating null-character */
        if (local == NULL) /* add error check again */
        {
            perror("malloc 2");
            return 1;
        }
        //malloc a dynamic string of only the length needed

        //To lowercase, so Job and job is considered the same word
        /* using strlen() in loop condition is not a good idea.
         * you have already calculated it, so use it. */
        for(u = 0; u < p; u++)
        {
            /* cast to unsigned char in order to avoid undefined behavior
             * for passing out-of-range value */
            input[u] = tolower((unsigned char)input[u]);
        }

        strcpy(local, input);
        curr->word = local; /* do not use strcpy, just assign */

        insert(&root, curr);
    }

    /* code to free what is allocated will be here */
    return 0;
}

//Separate insert function
void insert(node ** tree, node * item)
{
   if(!(*tree))
   {
      *tree = item;
      return;
   }
        if(strcmp(item->word,(*tree)->word) < 0)
            insert(&(*tree)->left, item);
        else if(strcmp(item->word,(*tree)->word) > 0)
            insert(&(*tree)->right, item);
        /* note: memory leak may occur if the word read is same as what is previously read */
}

关于从 C 文件创建动态分配的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35857535/

相关文章:

c - 文件中带有变音符号的 y

c - printf() 的意外行为

python - 在 Python 中遍历一棵不寻常的树

python - 广度优先树生成的问题

python - python中的递归和return语句

c - 为什么只有 1% 的时间我会得到不同的结果?

c++ - 将共享库转换为静态库?

c - 有范围的东西

c# - 更改/导航到树的特定节点?

algorithm - 如何解决这个线性编程问题?