【问题标题】:Creating a function that returns an array of strings创建一个返回字符串数组的函数
【发布时间】:2019-09-08 22:16:04
【问题描述】:

我正在尝试创建一个字符串解析器,它使用分隔符将字符串分解为字符串数组。我正在使用我了解如何使用的函数“strtok”。我不明白的是如何让我的解析函数返回字符串中不同单词的数组。自从我使用 C 以来已经有一段时间了,所以这被证明是相当困难的。

char ** parseString(char * inString){

    char **ptr; //What I want to return, an array of strings
    int count = 0;

    ptr[count] = strtok(inString, " ");
    count++;
    while(inString!=NULL){
         ptr[count]=strtok(NULL, " ");
         count++;
    }
    return ptr;
}

我知道上面的代码行不通。我隐约记得如何使用malloc,并且我知道我上面的代码会导致seg fault,因为我没有malloced,但上面基本上是我想要发生的。如果我什至不知道我的字符串数组中需要多少个单词,我该如何适当地 malloc?

【问题讨论】:

  • 选项 1) 猜一猜。如果数组填满,realloc 使其更大。如果你把它太大了,realloc 最后让它变小。
  • 选项2),解析字符串两次。第一次,您只需计算阵列需要多大。第二次做实际工作
  • 什么时候,inString指向的数据需要保持原来的样子?

标签: c


【解决方案1】:

对于分配向量,因为你从一开始就不知道它的大小,所以有几个策略:

  • 可以先解析inString得到字数,分配后再解析。
  • 您可以为每个单词重新分配。
  • 您可以以几何级数增长重新分配。

在第一个变体中,您进行了两次解析,使其成为最糟糕的一个

第二个有多次重新分配的缺点,但在小字符串和函数不重要的情况下是可以接受的。

第三个是最好的,是 C++ 中的std::vector 所做的。

我在这里向您展示第二个变体。

您还需要将向量的大小保存在单独的变量中。

char** parseString(char* inString, size_t* tokensLen)
{
    char **tokens = NULL; // realloc on NULL acts like malloc so we simplify the code
    size_t i = 0;

    // parse the first word
    char* inToken = strtok(inString, " ");

    while (inToken)
    {
        // allocate for one more pointer
        tokens = realloc(tokens, (i + 1) * sizeof *tokens);
        assert(tokens);

        // point to word
        tokens[i] = inToken;

        // parse the next word
        inToken = strtok(NULL, " ");
        ++i;
    }

    // set size
    *tokensLen = i;

    return tokens;
}
int main()
{
    char str[] = "here we go";
    size_t len;
    char** tokens = parseString(str, &len);

    for (size_t i = 0; i < len; ++i)
    {
        printf("%s\n", tokens[i]);
    }
}

【讨论】:

  • 非常感谢,这很有意义!
  • size_t* tokensLenint i = 0; 使用相同的类型更有意义。建议size_t
  • @mattgallant24 欢迎您。如果您认为这有助于您考虑支持它。如果它回答了您的问题,请考虑将其标记为已接受。
  • 这个答案修改了原始字符串。那是(IMO)一种糟糕的做法。建议使用strlen()malloc() 将字符串复制到本地动态数组。并在那里执行所有解析
猜你喜欢
  • 2018-12-16
  • 2011-09-04
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 2021-01-21
  • 2013-04-14
相关资源
最近更新 更多