【问题标题】:Making an array of tokens from string with strtok, malloc, and realloc使用 strtok、malloc 和 realloc 从字符串创建一个标记数组
【发布时间】:2017-07-26 20:35:28
【问题描述】:

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

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

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
}

【问题讨论】:

  • malloc/strcpy 可以替换为strdup
  • *(array+j) : NULL 作为哨兵的区域没有被保护和存储。并添加调用者的代码。
  • @EugeneSh., strdup 不在标准 C 语言中(但广泛使用),所以如果这是某种练习,这可能会有问题。
  • 打印循环会尝试迭代,直到遇到一个 NULL 指针,但您不能确保列表末尾有一个 NULL 指针。
  • @FlorianWeimer-- it is POSIX,原来如此......

标签: c arrays malloc realloc strtok


【解决方案1】:

您应该在指针数组后面附加一个空指针。否则不知道数组包含多少元素。

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

#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

【讨论】:

  • 因为我是一个 nube,所以我不能投票 cmets 或答案,所以感谢您提供关于以 NULL 指针结束数组的提示。事实证明这非常有用。一路走来,我还学会了不要嵌套调用 strtok。浪费了一两天时间。
  • @phlatphish 您可以选择最佳答案,在这种情况下为单个答案。:)
猜你喜欢
  • 1970-01-01
  • 2016-02-23
  • 2015-06-26
  • 2011-08-21
  • 2021-05-31
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多