1

我正在尝试在 C 中编写一个函数,它接受一个指向以结尾的连续字符的指针'\0'- 即一个字符串 - 和一个单个常量字符分隔符,然后输出一个指向连续指针的指针,每个指针都指向一个新字符串. 这些新字符串对应于在每个分隔符处断开并正确终止的输入字符串。简而言之,我想动态构建一个字符串数组。

为此,我计划使用 malloc() 来分配我需要的内存。“父数组”将是sizeof(char *) * (count + 2)字节长,以容纳指向每个分隔子字符串的第一个字符的指针,加上一个终止符。同样,每个“子数组”将是sizeof(char) * (j + 1)字节长,以容纳每个子字符串的所有字符,再加上一个终止符。

到目前为止,我的代码是这样的。

#include <stdio.h>
#include <stdlib.h>

char *split(char *string, const char delimiter);

int main(int argc, char *argv[]) {
    char *x = split(argv[1], '.');
    while (*x) {
        printf("%d\n", *x);
    }
    return 0;
}

char *split(char *string, const char delimiter) {
    int length, count, i, j = 0;
    while(*(string++)) {
        if (*string == delimiter) count++;
        length++;
    }
    string -= length;
    char *array = (char *)malloc(sizeof(char *) * (length + 1));
    for(i, j = 0; i < (count + 1); i++) {
        while(*(string++) != delimiter) j++;
        string -= j;
        *array = (char *)malloc(sizeof(char) * (j + 1));
        while(*(string++) != delimiter) *(*array++) = *(string++);
        **array = '\0';
        string++;
        array += sizeof(char *);
    }
    *array = '\0';
    array -= (sizeof(char *) * (length + 1));
    return array;  
}

我的问题是为什么编译器会吐出以下错误?

split2.c: In function ‘split’:
split2.c:25: warning: assignment makes integer from pointer without a cast
split2.c:26: error: invalid type argument of ‘unary *’ (have ‘int’)
split2.c:27: error: invalid type argument of ‘unary *’ (have ‘int’)

我的猜测是,当分配“父数组”的内存时,编译器int期望值,而不是char *存储在那里。如果是这种情况,我该如何正确更正我的代码?

我知道有更简单的方法可以使用string.h; 我编写此代码的动机是更好地了解指针在 C 中的工作方式。

提前谢谢了!

4

3 回答 3

3

我想你想要array一个双指针,char **array.

char **array = (char **)malloc(sizeof(char *) * (length + 1));

正如您的逻辑所说,您需要一个 数组char*,每个数组都指向一个字符串。所以array应该是双指针。如果您进行此修改,请将返回类型也更改为char**.

如果你想使用双指针,试试这个:

char **split(char *string, const char delimiter) {
    int length = 0, count = 0, i = 0, j = 0;
    while(*(string++)) {
        if (*string == delimiter) count++;
        length++;
    }
    string -= (length + 1); // string was incremented one more than length
    char **array = (char **)malloc(sizeof(char *) * (length + 1));
    char ** base = array;
    for(i = 0; i < (count + 1); i++) {
        j = 0;
        while(string[j] != delimiter) j++;
        j++;
        *array = (char *)malloc(sizeof(char) * j);
        memcpy(*array, string, (j-1));
        (*array)[j-1] = '\0';
        string += j;
        array++;
    }
    *array = '\0';
    return base;  
}

稍后释放此数组,例如:

i = 0;
while(base[i]) {
    free(base[i]);
    i++;
}
free(base);
base = NULL;
于 2013-06-12T09:02:07.493 回答
2
    *array = (char *)malloc(sizeof(char) * (j + 1));

应该

    array = (char *)malloc(sizeof(char) * (j + 1));  // malloc returns a pointer, no need to dereference here

然后这个

    while(*(string++) != delimiter) *(*array++) = *(string++);

应该

    while(*(string++) != delimiter) *array++ = *(string++); // dereferenceing once would do

最后这个

    **array = '\0';

应该

    *array = '\0'; // same as above

上述所有变化的原因都是一样的。array是指针而不是指向指针的指针。

此外,在您的代码中,循环索引i从未被初始化,因此必然会导致不确定的行为。要么在声明中初始化它,比如

int length, count, i = 0, j = 0;

或在循环初始化中

for(i = 0, j = 0; i < (count + 1); i++) {

希望这可以帮助!

于 2013-06-12T08:58:24.140 回答
0
char *array = (char *)malloc(sizeof(char *) * (length + 1));

应该

char **array = (char **)malloc(sizeof(char **) * (length + 1));

*array = (char *)malloc(sizeof(char) * (j + 1));

应该

array[i] = (char *)malloc(sizeof(char) * (j + 1));

您似乎是初学者,我建议您更喜欢 array[i] 而不是使用 *array 或其他指针操作,这在开始时更简单。

于 2013-06-12T09:09:10.477 回答