Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用strtok、malloc和realloc从字符串生成令牌数组_C_Arrays_Malloc_Realloc_Strtok - Fatal编程技术网

使用strtok、malloc和realloc从字符串生成令牌数组

使用strtok、malloc和realloc从字符串生成令牌数组,c,arrays,malloc,realloc,strtok,C,Arrays,Malloc,Realloc,Strtok,有些话题与此部分重叠,但我仍在寻求答案 标记化部分工作正常,但动态内存分配似乎不正常,这是基于打印循环未注释时的segfault free()只是检查free()是否工作,而不是作为已完成函数的一部分,它将返回NULL,直到它能够返回合理的值为止 sep通常是一个空格。行尾的任何\n都会在到达之前处理好 char ** chunkify(char *line, char *sep) { printf("%s\n", line); char **array = malloc(size

有些话题与此部分重叠,但我仍在寻求答案

标记化部分工作正常,但动态内存分配似乎不正常,这是基于打印循环未注释时的segfault

free()只是检查free()是否工作,而不是作为已完成函数的一部分,它将返回NULL,直到它能够返回合理的值为止

sep通常是一个空格。行尾的任何\n都会在到达之前处理好

char ** chunkify(char *line, char *sep)
{
   printf("%s\n", line);

   char **array = malloc(sizeof(char *));        
   int token_count = 0;
   char *token = NULL;   
   token = strtok(line, sep);

   while( token != NULL )
   {              
      printf("\t%s\n", token);
      array = realloc(array,(token_count + 1) * sizeof(char *));      
      array[token_count] = malloc(strlen(token) + 1);
      strcpy(array[token_count],token);
      token = strtok(NULL, sep);
      token_count++;
   }  

   /*
   int j;
   for ( j=0 ; *(array+j) ; ++j)
   {
      printf("\t%s\n", *(array+j));
      free(*(array+j)); // just to see if it frees cleanly
   }
   free(array);
   */

   return NULL; // will return array when it's fixed
}

应该使用空指针附加指针数组。否则,不知道数组包含多少个元素

如果您使用的方法不够聪明,因为它没有报告分配错误,那么该函数看起来就像这个演示程序中所示

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

char ** chunkify( char *line, const char *sep )
{
    char **array = malloc( sizeof( char * ) );

    if ( array )
    {
        size_t n = 1;

        char *token = strtok( line, sep );

        while ( token )
        {
            char **tmp = realloc( array, ( n + 1 ) * sizeof( char * ) );

            if ( tmp == NULL ) break;

            array = tmp;
            ++n;

            array[ n - 2 ] = malloc( strlen( token ) + 1 );
            if ( array[ n - 2 ] != NULL ) strcpy( array[ n - 2 ], token );

            token = strtok( NULL, sep );
        }

        array[ n - 1 ] = NULL;
    }

    return array;
}

int main(void) 
{
    char s[] = "Hello World";
    char **array = chunkify( s, " " );

    if ( array != NULL )
    {
        for ( char **p = array; *p; ++p ) puts( *p );

        for ( char **p = array; *p; ++p ) free( *p );
        free( array );
    }       

    return 0;
}

malloc/strcpy
可替换为
strdup
*(数组+j)
:未保护和存储哨兵的
NULL
区域。并添加调用者的代码。@EugeneSh.,
strdup
不在标准C中(但广泛可用),因此如果这是某种练习,这可能会有问题。打印循环尝试迭代直到遇到空指针,但您不能确保列表末尾有空指针。@FlorianWeimer--,这就是…因为我是nube,所以我无法对评论或答案进行投票,所以感谢您提供的关于使用空指针结束数组的提示。这证明是非常有用的。一路上,我也学会了不要给strtok打电话。在这件事上损失了一两天。@phlatphish您可以选择最好的答案,在本例中,这是一个单一的答案。:)
Hello
World