Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 编写函数拆分字符串_C - Fatal编程技术网

C 编写函数拆分字符串

C 编写函数拆分字符串,c,C,我正在尝试编写一个函数来拆分字符串(不使用strtok),以了解它是如何工作的。到目前为止,我已经得出了以下结论: char ** split_string(char * string, char sep) { // Allow single separators only for now // get length of the split string array int array_length = 0; char c; for (int i=0

我正在尝试编写一个函数来拆分字符串(不使用strtok),以了解它是如何工作的。到目前为止,我已经得出了以下结论:

char ** split_string(char * string, char sep) {
    // Allow single separators only for now

    // get length of the split string array
    int array_length = 0;
    char c;

    for (int i=0; (c=string[i]) != 0; i++)
        if (c == sep) array_length ++;

    // allocate the array
    char * array[array_length + 1];
    array[array_length] = '\0';

    // add the strings to the array
    for (int i=0, word=0; (c=string[i]) != 0;) {
        if (c == sep) {
            i=0;
            word ++;
        } else {
            array[i][word] = c;
            i++;
        }
    }

    return array;

}
这是我第一次使用指向指针(字符串列表)的指针,所以我有点不清楚如何执行此操作,您可能可以从上面的函数中看出这一点


如何正确地做到这一点?具体来说,返回类型是否正确?如何将
\0
添加到数组的末尾

您犯的一个错误是没有为要复制的单词分配空间。复制之前,必须为目标数组中的字显式分配空间。以下程序实现了预期目标。要知道字数,请将
array\u length
声明为全局变量,以便在调用
split\u string
的函数中使用该变量

int array_length=0;
char** split_string(char* str, char sep){

    for(int i = 0;str[i] != '\0';++i){
        if(str[i] == sep) ++array_length;

    char** str_arr = (char**)malloc(sizeof(char*) * (array_length+1));
    for(int i=0, j, k = 0; str[i] != '\0'; ++k){     // k is used to index the destination array for the extracted word
        for(j = i; str[j] != sep && str[j] != '\0'; ++j);   // from the current character, find the position of the next separator
        str_arr[k] = (char*)malloc((j-i+2)*sizeof(char));    // Allocate as many chars in the heap and make str_arr[k] pointer point to it
        strncpy(str_arr[k], str+i, j-i);       // copy the word to the allocated space
        i=j+1;              // move the array iterator to the next non-sep character
    }
    return str_arr;
}
如果不想显式使用
malloc
,也可以使用库函数
strndup
,它将指向源字符串起始字符的指针和要复制的字符数作为输入,进行内存分配,复制单词并返回指向分配空间的指针。函数中有两行

str_arr[k] = (char*)malloc((j-i+2)*sizeof(char));    // Allocate as many chars in the heap and make str_arr[k] pointer point to it
strncpy(str_arr[k], str+i, j-i); 
可以用一行替换,如下所示-

str_arr[k] = strndup(str+i, j-i);
但我建议初学者使用第一种方法,以便更好地理解和调试


注意:上述程序仅适用于单词之间的单个分隔符,如果单词之间出现多个连续分隔符,则必须稍微调整程序才能使其正常工作

好的,但是您会失望,因为您已经声明了指向函数的本地指针数组,这样当
split_string
返回时,您的
char*array[array_length+1]变得无效。。。。如果需要指针数组,则动态分配,以使存储不在函数堆栈上,而是在堆上,并且在函数返回后仍然有效。选项2-如果只是一分为二,您只需返回一个指向原始字符串中的地址的指针,该地址是字符串的第二部分开始的位置。您不应使用
C
语言强制转换返回
void*
的函数的返回值,如
malloc
。任何强制转换都可以隐藏bug,并且在
C
中不需要将
void*
强制转换到特定指针。