【问题标题】:Writing a function to split a string编写一个函数来分割字符串
【发布时间】:2019-09-10 05:51:12
【问题描述】:

我正在尝试编写一个函数来拆分字符串(不使用 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 添加到数组的末尾?

【问题讨论】:

  • 好吧,但是你会感到失望,因为你已经声明了函数的本地指针数组,这样当split_string 返回时,你的char * array[array_length + 1]; 变得无效......如果你想动态分配一个指针数组,以便存储不在函数堆栈上,而是在堆上,并且将在函数返回后继续存在。选项 2 - 如果只是一分为二,您可以简单地返回一个指向原始字符串中的地址的指针,该地址将开始字符串的第二部分。

标签: c


【解决方案1】:

您犯的一个错误是没有为要复制的单词分配空间。在复制之前,您必须为目标数组中的单词显式分配空间。以下程序实现了预期目标。要知道字数,请将array_length 声明为全局变量,以便您可以在调用split_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);

但我建议初学者使用第一种方法,以便更好地理解和调试。

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

【讨论】:

  • 您不应在C 语言中转换返回void* 的函数的返回值,例如malloc。任何转换都可以隐藏错误,并且在C 中不需要将void* 转换为特定指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 2012-09-10
  • 2020-10-04
相关资源
最近更新 更多