在c中将长动态字符串拆分为字符串数组
Posted
技术标签:
【中文标题】在c中将长动态字符串拆分为字符串数组【英文标题】:splitting a long dynamic string into an array of strings in c 【发布时间】:2022-01-21 02:47:08 【问题描述】:我对 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
创建的。
【问题讨论】:
temp = realloc(finalValue, sizeof(char*));
为单个指针分配内存。有什么意义?
idk 我必须从原始字符串中创建多少个字符串,所以每次迭代时,我都会为另一个字符串创建一个位置
【参考方案1】:
问题就在这里:temp = realloc(finalValue, sizeof(char *));
为单个指针重新分配。你应该写:
temp = realloc(finalValue, (wordIndex + 2) * sizeof(char *));
您还应该在finalValue
数组的末尾设置一个NULL
指针,以标记该数组的末尾,因为该函数不会以任何其他方式返回条目数。
另请注意,当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;
【讨论】:
以上是关于在c中将长动态字符串拆分为字符串数组的主要内容,如果未能解决你的问题,请参考以下文章