用给定的分隔符分割字符串的函数
Function that divides the string with given delimiter
我有一个名为 ft_split(char const *s, char c)
的函数,它应该接受字符串和分隔符字符 c
并将 s
分成一堆较小的字符串。
这是我尝试解决它的第 3 天或第 4 天,我的方法是:
计算没有。当时字符串中的字符数包括 1 个定界符(如果 space 是定界符,那么如果连续有 2 个或更多 space 比它计算一个 space 而不是更多。为什么? 那个space是一个内存,用于在每个拆分字符串的末尾添加'\0')
它找到分隔符之间的字符大小 (k) -> malloc 内存 -> 从字符串复制到 malloc -> 从 malloc 复制到 malloc -> 重新开始。
但是好吧...函数显示分段错误。调试器显示在分配“大”内存后,它不会进入 while 循环,而是在退出函数后直接进入 big[y][z] = small[z]。
感谢任何提示。
#include "libft.h"
#include <stdlib.h>
int ft_count(char const *s, char c)
{
int i;
int j;
i = 0;
j = 0;
while (s[i] != '[=11=]')
{
i++;
if (s[i] == c)
{
i++;
while (s[i] == c)
{
i++;
j++;
}
}
}
return (i - j);
}
char **ft_split(char const *s, char c)
{
int i;
int k;
int y;
int z;
char *small;
char **big;
i = 0;
y = 0;
if (!(big = (char **)malloc((ft_count(s, c) + 1) * sizeof(char))))
return (0);
while (s[i] != '[=12=]')
{
while (s[i] == c)
i++;
k = 0;
while (s[i] != c)
{
i++;
k++;
}
if (!(small = (char *)malloc(k * sizeof(char) + 1)))
return (0);
z = 0;
while (z < k)
{
small[z] = s[i - k + z];
z++;
}
small[k] = '[=12=]';
z = 0;
while (z < k)
{
big[y][z] = small[z];
z++;
}
y++;
free(small);
}
big[y][i] = '[=12=]';
return (big);
}
int main()
{
char a[] = "jestemzzbogiemzalfa";
ft_split(a, 'z');
}
我没有完全理解代码的作用,但是:
你有一个 char **big
,它是一个指向字符的指针,所以大概应该指向一个 char *
的数组,然后指向字符串。看起来像这样:
[ big (char **) ] -> [ big[0] (char *) ][ big[1] (char *) ][ big[2] ... ]
| [
v v
[ big[0][0] (char) ] ...
[ big[0][1] (char) ]
[ big[0][2] (char) ]
[ ... ]
这里,当你调用big = malloc(N * sizeof(char *))
时,你为中间的指针分配space,big[0]
到big[N-1]
,水平数组中右上角的指针.它仍然没有将它们设置为任何东西,也没有为最终字符串保留 space(big[0][x]
等)
相反,您需要执行类似
的操作
big = malloc(N * sizeof(char *));
for (i = 0; i < N; i++) {
big[i] = malloc(k);
}
单独为每个最终字符串设置正确的大小等。或者一次性分配一个大区域,并将其拆分为最终字符串。
现在,在您的代码中,您似乎从未将任何东西分配给 big[y]
,因此它们可能是任何东西,这很可能解释了引用 big[y][z]
时的段错误。如果您使用 calloc()
,那么现在 big[y]
是 NULL,而 malloc()
可能是,也可能不是。
此外,这里:
while (s[i] != '[=12=]')
{
while (s[i] == c)
i++;
k = 0;
while (s[i] != c) /* here */
{
i++;
k++;
}
我想知道如果在 while (s[i] != c)
处到达字符串末尾会发生什么,即如果 s[i]
在该点是 '[=26=]'
?循环应该会停止,但它看起来不像。
代码中存在多个问题:
ft_count()
函数不正确:您在测试分隔符之前递增 i
,因此如果字符串以分隔符开头,则数字不正确。您应该改为计算从分隔符到非分隔符的转换次数:
int ft_count(char const *s, char c)
{
char last;
int i;
int j;
last = c;
i = 0;
j = 0;
while (s[i] != '[=10=]')
{
if (last == c && s[i] != c)
{
j++;
}
last = s[i];
i++;
}
return j;
}
此外,ft_split()
函数也不正确:
- 分配给
big
指针数组的内存量无效:您应该将元素数乘以元素大小,这不是 char
而是 char *
。
- 如果字符串以分隔符结尾,则在数组末尾添加一个空字符串。您应该在跳过分隔符后测试空字节。
- 您在扫描项目后的分隔符时没有测试空终止符。
- 您没有将
small
指针存储到 big
指针数组中。不要将字符串复制到 big[y][...]
,您应该只设置 big[y] = small
而不是 free(small)
.
这是修改后的版本:
char **ft_split(char const *s, char c)
{
int i;
int k;
int y;
int z;
char *small;
char **big;
if (!(big = (char **)malloc((ft_count(s, c) + 1) * sizeof(*big))))
return (0);
i = 0;
y = 0;
while (42) // aka 42 for ever :)
{
while (s[i] == c)
i++;
if (s[i] == '[=11=]')
break;
k = 0;
while (s[i + k] != '[=11=]' && s[i + k] != c)
{
k++;
}
if (!(small = (char *)malloc((k + 1) * sizeof(char))))
return (0);
z = 0;
while (z < k)
{
small[z] = s[i];
z++;
i++;
}
small[k] = '[=11=]';
big[y] = small;
y++;
}
big[y] = NULL;
return (big);
}
42 咆哮:
Ces conventions de codage (la norminette) 反对生产! Les boucles for
sont plus lisibles et plus sûres que ces while
, les casts sur les valeurs de retour de malloc()
sont inutiles et confusantes, les parenthèses autour de l'argument de return
sont infantiles.
我有一个名为 ft_split(char const *s, char c)
的函数,它应该接受字符串和分隔符字符 c
并将 s
分成一堆较小的字符串。
这是我尝试解决它的第 3 天或第 4 天,我的方法是:
计算没有。当时字符串中的字符数包括 1 个定界符(如果 space 是定界符,那么如果连续有 2 个或更多 space 比它计算一个 space 而不是更多。为什么? 那个space是一个内存,用于在每个拆分字符串的末尾添加'\0')
它找到分隔符之间的字符大小 (k) -> malloc 内存 -> 从字符串复制到 malloc -> 从 malloc 复制到 malloc -> 重新开始。
但是好吧...函数显示分段错误。调试器显示在分配“大”内存后,它不会进入 while 循环,而是在退出函数后直接进入 big[y][z] = small[z]。
感谢任何提示。
#include "libft.h"
#include <stdlib.h>
int ft_count(char const *s, char c)
{
int i;
int j;
i = 0;
j = 0;
while (s[i] != '[=11=]')
{
i++;
if (s[i] == c)
{
i++;
while (s[i] == c)
{
i++;
j++;
}
}
}
return (i - j);
}
char **ft_split(char const *s, char c)
{
int i;
int k;
int y;
int z;
char *small;
char **big;
i = 0;
y = 0;
if (!(big = (char **)malloc((ft_count(s, c) + 1) * sizeof(char))))
return (0);
while (s[i] != '[=12=]')
{
while (s[i] == c)
i++;
k = 0;
while (s[i] != c)
{
i++;
k++;
}
if (!(small = (char *)malloc(k * sizeof(char) + 1)))
return (0);
z = 0;
while (z < k)
{
small[z] = s[i - k + z];
z++;
}
small[k] = '[=12=]';
z = 0;
while (z < k)
{
big[y][z] = small[z];
z++;
}
y++;
free(small);
}
big[y][i] = '[=12=]';
return (big);
}
int main()
{
char a[] = "jestemzzbogiemzalfa";
ft_split(a, 'z');
}
我没有完全理解代码的作用,但是:
你有一个 char **big
,它是一个指向字符的指针,所以大概应该指向一个 char *
的数组,然后指向字符串。看起来像这样:
[ big (char **) ] -> [ big[0] (char *) ][ big[1] (char *) ][ big[2] ... ]
| [
v v
[ big[0][0] (char) ] ...
[ big[0][1] (char) ]
[ big[0][2] (char) ]
[ ... ]
这里,当你调用big = malloc(N * sizeof(char *))
时,你为中间的指针分配space,big[0]
到big[N-1]
,水平数组中右上角的指针.它仍然没有将它们设置为任何东西,也没有为最终字符串保留 space(big[0][x]
等)
相反,您需要执行类似
的操作big = malloc(N * sizeof(char *));
for (i = 0; i < N; i++) {
big[i] = malloc(k);
}
单独为每个最终字符串设置正确的大小等。或者一次性分配一个大区域,并将其拆分为最终字符串。
现在,在您的代码中,您似乎从未将任何东西分配给 big[y]
,因此它们可能是任何东西,这很可能解释了引用 big[y][z]
时的段错误。如果您使用 calloc()
,那么现在 big[y]
是 NULL,而 malloc()
可能是,也可能不是。
此外,这里:
while (s[i] != '[=12=]')
{
while (s[i] == c)
i++;
k = 0;
while (s[i] != c) /* here */
{
i++;
k++;
}
我想知道如果在 while (s[i] != c)
处到达字符串末尾会发生什么,即如果 s[i]
在该点是 '[=26=]'
?循环应该会停止,但它看起来不像。
代码中存在多个问题:
ft_count()
函数不正确:您在测试分隔符之前递增i
,因此如果字符串以分隔符开头,则数字不正确。您应该改为计算从分隔符到非分隔符的转换次数:
int ft_count(char const *s, char c)
{
char last;
int i;
int j;
last = c;
i = 0;
j = 0;
while (s[i] != '[=10=]')
{
if (last == c && s[i] != c)
{
j++;
}
last = s[i];
i++;
}
return j;
}
此外,ft_split()
函数也不正确:
- 分配给
big
指针数组的内存量无效:您应该将元素数乘以元素大小,这不是char
而是char *
。 - 如果字符串以分隔符结尾,则在数组末尾添加一个空字符串。您应该在跳过分隔符后测试空字节。
- 您在扫描项目后的分隔符时没有测试空终止符。
- 您没有将
small
指针存储到big
指针数组中。不要将字符串复制到big[y][...]
,您应该只设置big[y] = small
而不是free(small)
.
这是修改后的版本:
char **ft_split(char const *s, char c)
{
int i;
int k;
int y;
int z;
char *small;
char **big;
if (!(big = (char **)malloc((ft_count(s, c) + 1) * sizeof(*big))))
return (0);
i = 0;
y = 0;
while (42) // aka 42 for ever :)
{
while (s[i] == c)
i++;
if (s[i] == '[=11=]')
break;
k = 0;
while (s[i + k] != '[=11=]' && s[i + k] != c)
{
k++;
}
if (!(small = (char *)malloc((k + 1) * sizeof(char))))
return (0);
z = 0;
while (z < k)
{
small[z] = s[i];
z++;
i++;
}
small[k] = '[=11=]';
big[y] = small;
y++;
}
big[y] = NULL;
return (big);
}
42 咆哮:
Ces conventions de codage (la norminette) 反对生产! Les boucles
for
sont plus lisibles et plus sûres que ceswhile
, les casts sur les valeurs de retour demalloc()
sont inutiles et confusantes, les parenthèses autour de l'argument dereturn
sont infantiles.