我正在尝试创建split()
函数,将char*
拆分为2D数组或char**
void split(char* str, char d, char** into)
{
if(str != NULL || into != NULL)
{
int n = 0;
int c = 0;
for(int i = 0; str[c] != '\0'; i++,c++)
{
into[n][i] = str[c];
if(str[c] == d)
{
into[n][i] = '\0';
i = 0;
++n;
}
}
}
}
int main()
{
char** sa = (char**)malloc(50*sizeof(char*));
memory.allocarr(sa, 512, 50);
split("Hello;World;", ';', sa);
puts(sa[0]);
return 0;
}
memory.allocarr
是结构中指向以下函数的指针
void memory_allocate_array(char** pointers, int bytes, int slots) // memory.allocarr
{
int i = 0;
while(i <= slots)
{
pointers[i] = (char*)calloc(1, bytes);
++i;
}
}
我的功能仅拆分并填充数组的第一个插槽(sa[0]
)
puts(sa[0]); // Prints "Hello"
puts(sa[1]); // Prints ""
puts(sa[2]); // Prints "" ...
我试过调试它
for(int i = 0; str[c] != '\0'; i++,c++)
{
printf("n:%d\ti:%d\tc:%d\n",n,i,c);
into[n][i] = str[c];
if(str[c] == d)
{
into[n][i] = '\0';
i = 0;
++n;
}
puts(into[n]);
}
输出
n:0 i:0 c:0
H
n:0 i:1 c:1
He
n:0 i:2 c:2
Hel
n:0 i:3 c:3
Hell
n:0 i:4 c:4
Hello
n:0 i:5 c:5
n:1 i:1 c:6
n:1 i:2 c:7
n:1 i:3 c:8
n:1 i:4 c:9
n:1 i:5 c:10
n:1 i:6 c:11
我仍然不知道到底出了什么问题,你能帮我搞清楚吗?
答案 0 :(得分:2)
你有两个问题。
第一个是次要的,这是一个逻辑错误:
if(str != NULL || into != NULL)
只有当str
和into
都不是NULL
时才想进行拆分。所以
正确的条件是:
if(str != NULL && into != NULL)
请注意,a || b
相当于!a && !b
。
第二个问题在这里:
if(str[c] == d)
{
into[n][i] = '\0';
i = 0; // <--- here
++n;
}
这个想法没问题,但是当你将i
重置为0时,会执行下一次迭代,但是
在此之前,i++,c++
循环的for
也会被执行。为了
第二,第三,第四等迭代i
以1开头。因为您使用calloc
进行分配
在你的记忆中,into[n][i]
全都为0,而into[n][i] = str[c];
则为{0}
迭代正在进行into[n][1] = str[c]
。所以你要创建这个字符串:
+----+---+---+---+---+---+----+
into[n]: | \0 | W | o | r | l | d | \0 |
+----+---+---+---+---+---+----+
for all n >= 1
字符串中的第一个字符已经是'\ 0'终止字节,所以
puts
打印一个空行。
如何解决?像这样:
if(str[c] == d)
{
into[n][i] = '\0';
i = -1;
++n;
}
因此,当第二次,第三次等迭代开始时,i
为0。
我接受了您的代码并进行了修复,我得到了Hello
和World
是
另外不要忘记释放所有已分配的内存。写一个功能 将双指针作为参数和它的长度,类似于 这样:
void free_string_matrix(char **matrix, size_t len)
{
if(matrix == NULL || *matrix == NULL)
return;
for(size_t i = 0; i < len; ++i)
free(matrix[i]);
free(matrix);
}