使用 strtok、malloc 和 realloc 从字符串创建一个标记数组

Making an array of tokens from string with strtok, malloc, and realloc

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

标记化部分工作正常,但动态内存分配似乎不是,基于取消注释打印循环时的段错误。

free() 只是为了检查 free() 是否工作,而不是完成函数的一部分,并且它是 returning NULL 直到它可以 return 一些合理的东西。

sep 通常是 space。行尾的任何 \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;
}

程序输出为

Hello
World