实现2D split()函数

时间:2018-03-06 01:42:42

标签: c arrays multidimensional-array split

我正在尝试创建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

我仍然不知道到底出了什么问题,你能帮我搞清楚吗?

1 个答案:

答案 0 :(得分:2)

你有两个问题。

第一个是次要的,这是一个逻辑错误:

if(str != NULL || into != NULL)

只有当strinto都不是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。

我接受了您的代码并进行了修复,我得到了HelloWorld

另外不要忘记释放所有已分配的内存。写一个功能 将双指针作为参数和它的长度,类似于 这样:

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);
}