我试图在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’)
我的猜测是当&#34;父数组&#34;的内存时在分配时,编译器期望int
值,而不是char *
将存储在那里。如果是这种情况,我该如何正确更正我的代码?
我知道使用string.h
进行此类操作的方法要容易得多;我写这段代码的动机是更好地学习指针在C中的工作方式。
非常感谢提前!
答案 0 :(得分: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;
答案 1 :(得分: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++) {
希望这有帮助!
答案 2 :(得分: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]而不是使用*数组或其他指针操作,这在开始时更简单。