2016-03-08 62 views
1

我在动态分配树中节点的字符串时遇到了一些问题。我已经在下面包含了我的节点结构以供参考。从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); 
} 

要完全清楚,我只希望关于我的代码逻辑的建议,只希望有人帮我指出了正确的方向。

+0

注意,他们说[你不应该投的malloc'()的结果在'C](HTTP:// STA ckoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)。 – MikeCAT

+0

@MikeCAT。我知道这是一个错误,但我也不确定如何修复它。 &是我通常如何存储变量的值,但对于char数组,应该只是fscanf(ifp,“%s”,input)呢?此外,对于第三个评论,我应该也许只是使用一个循环并分配char值来确保我也复制null零? – Ash

+0

是的,应该是。 '&'用于检索指向对象(变量)的指针。你使用'&hoge'来检索指向'int hoge;'的指针。数组自动转换为指向数组第一个元素的指针,所以您不必使用'&'来检索传递给'fscanf()'的指针。 – MikeCAT

回答

0

你被

  • 调用很多不确定的行为,传递指针目标对象的类型错误scanf()。即在fscanf(ifp, "%s", &input)char(*)[100]传递其中char*预计
  • 访问使用缓冲的值经由malloc()分配和strcpy(curr->word,local);
未初始化在 strcpy(local, input);
  • storeing终止空字符时外的范围分配的缓冲区的

    您的代码应该是这样的:

    #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 */ 
    } 
    
  • +0

    谢谢。我很高兴知道我在考虑如何执行动态分配的字符串时并没有这样做,但我只是在处理指针和malloc的时候关闭了它。感谢您的帮助。 – Ash