繁体   English   中英

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

[英]Creating Dynamically Allocated Strings from a file in C

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

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*地方传递char(*)[100]
  • 当将终止空字符存储在strcpy(local, input);访问分配的缓冲区的范围外strcpy(local, input);
  • 使用通过malloc()分配且未在strcpy(curr->word,local);初始化的缓冲区的值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 */
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM