我对C非常陌生,我可以理解为什么这个函数没有一致地工作:
char **splitString(char *string) {
char *token = strtok(string, ","), **finalValue = NULL, **temp = NULL;
size_t wordIndex = 0;
while (token != NULL) {
temp = realloc(finalValue, sizeof(char *));
if (!temp) {
freeArray(finalValue);
finalValue = NULL;
break;
}
temp[wordIndex] = malloc((strlen(token)+1)*sizeof(char));
if (temp[wordIndex] == NULL) {
freeArray(finalValue);
finalValue = NULL;
break;
}
strcpy(temp[wordIndex], token);
printf("%s\n", temp[wordIndex]);
finalValue = temp;
printf("%s\n", finalValue[wordIndex]);
wordIndex++;
token = strtok(NULL, ",");
}
return finalValue;
}它接收一个由逗号分隔的字符串,并将它们拆分为不同的字符串,所有字符串都是通过malloc/realloc创建的。
发布于 2021-12-18 19:10:15
问题是:temp = realloc(finalValue, sizeof(char *));为单个指针重新分配。你应该写:
temp = realloc(finalValue, (wordIndex + 2) * sizeof(char *));您还应该在NULL数组的末尾设置一个finalValue指针,以标记该数组的结束,因为函数没有以任何其他方式返回条目的数量。
还请注意,当realloc()或malloc()失败时,分配的字符串不会被释放。
此外,您不应该使用strtok(),因为它修改了源字符串。推荐使用strspn()、strcspn()或手动测试和strndup()的替代方法。
最后,strtok()还有另一个可能适得其反的缺点:它认为任何分隔符序列都是单个分隔符,不会产生空令牌。如果使用空格作为分隔符,这是很好的,但对于","来说,这可能是不正确的,因为您可能期望"a,,c"生成3个标记:"a"、""和"c"。
下面是一个可以处理空令牌的修改版本:
char **splitString(const char *string) {
const char *p0, *p0;
size_t i = 0, n = 1;
char **array;
for (p = string; *p; p++) {
if (*p == ',')
n++;
}
array = calloc(sizeof(*array), n + 1);
if (array != NULL) {
array[n] = NULL; /* set a null pointer at the end of the array */
for (p = p0 = string, i = 0; i < n;) {
if (*p == ',' || *p == '\0') {
if ((array[i++] = strndup(p0, p - p0)) == NULL) {
/* allocation failure: free allocated strings and array */
while (i --> 0)
free(array[i]);
free(array);
array = NULL;
break;
}
if (*p == ',')
p0 = ++p;
else
p0 = p;
} else {
p++;
}
}
}
return array;
}strndup()是许多系统上可用的POSIX函数,这将是下一个版本的C标准的一部分。如果在您的目标上不可用,下面是一个简单的实现:
char *strndup(const char *s, size_t n) {
char *p;
size_t i;
for (i = 0; i < n && s[i]; i++)
continue;
p = malloc(i + 1);
if (p) {
memcpy(p, s, i);
p[i] = '\0';
}
return p;
}https://stackoverflow.com/questions/70405651
复制相似问题