【发布时间】:2021-05-07 04:10:14
【问题描述】:
我正在尝试编写一个函数,该函数将在不更改原始字符串的情况下沿空格 (' ') 拆分字符串,将所有标记放入数组中,然后返回该数组。我遇到的问题是返回指针。下面是我的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **split_line(char *ln) {
char **tokens, *tok, line[256];
int j;
strcpy(line, ln);
tokens = calloc(64, sizeof(char*));
for (int i = 0; i < 64; i++)
tokens[i] = calloc(64, sizeof(char));
tokens[0] = strtok(line, " ");
for (j = 1; (tok = strtok(NULL, " ")) != NULL && j < 63; j++)
tokens[j] = tok;
tokens[j] = NULL;
return tokens;
}
int main(void) {
char **cut_ln, *input;
input = "Each word in this string should be an element in cut_ln.";
cut_ln = split_line(input);
printf("`%s`\n", input);
for (int i = 0; cut_ln[i] != NULL; i++)
printf("[%d]: `%s`\n", i, cut_ln[i]);
return 0;
}
运行时,会给出:
`This word in this string should be an element in cut_ln.`
[0]: `This`
[1]: `wo1`
[2]: `�={G+s`
[3]: `G+s`
[4]: `string`
[5]: ``
[6]: `0����`
[7]: `��`
[8]: ``
[9]: ``
[10]: ``
当我尝试在split_line 函数中打印tokens 的内容时,它给出了预期的结果。但是,当 tokens 返回并分配给一个变量,然后打印时,它会给出如上所示的结果。我做错了什么?
【问题讨论】:
-
tokens[j] = tok;覆盖了您用calloc仔细分配的指针,导致内存泄漏。您是否打算改为写strcpy(tokens[j], tok)之类的东西? -
strdup()然后strok()。不要重新发明轮子。如果您确实要重新发明它,请至少在快速扫描中先计算条目数,然后分配,然后返回。不要只是假设 64 就足够了。那几乎总是错误的。号码64绝对没有理由出现在这里,你没有什么可以支持这个号码存在的原因。似乎是随意选择的。 -
我赞扬你编写这个函数——它是处理字符串输入的好方法。很高兴在您的工具包中拥有。 (我希望有这样的标准库函数。)另见this question。
-
@tadman 不知道
strdup。但是,it would appear 它不是 ISO C 的一部分。 -
除非你受到 ISO C 的特别限制,比如你在一些有限的平台上,那么可以肯定,但除此之外,一定程度的 POSIX 合规性实际上是给定的,即使在不符合 POSIX 的情况下也是如此Windows 等平台。当我们谈论现代 C 时,我们通常包括 POSIX,因为它随处可见。 GCC、clang 和 VCC 都支持它。一些用于长期死机操作系统的神秘 C89 编译器可能不会,就像我不会指望它出现在 Microsoft XENIX 中一样。
标签: c split dynamic-memory-allocation c-strings function-definition