分裂字符串函数的分段错误

时间:2017-11-17 21:42:24

标签: c arrays string pointers

我需要编写一个将字符串拆分为单个单词的函数 我的第一个参数是一个字符串。我们假设字符串中的单词由单个空格分隔,在第一个单词之前或第二个单词之后没有空格。例如空格的标点符号是单词的一部分。我的第二个参数是一个整数的地址,其中函数给它一个字符串中单词数的值。返回值是一个指针,指向包含句子中单个单词的字符串数组。我需要从堆中分配内存,并在数组的每个索引中有一个单词。字符串是原始单词的副本,而不是指针。这是我的代码:

char** splitString(char theString[], int *arraySize) {
  *arraySize = countSpaces(theString) + 1; //Points to the number of words in the string.
  char** pointerToArrayOfStrings = malloc(*arraySize * sizeof(char *)); //Allocated memory for '*arraySize' character pointers
  int characters = 0;
  for (int i = 0; i < *arraySize; i++) {
    while (theString[characters] != ' ' || theString[characters] != '\0') {
      characters++;
    }
    characters++;
    pointerToArrayOfStrings[i] = (char *)malloc(characters);
    pointerToArrayOfStrings[i][characters] = '\0';
  }
  for (int word = 0; word < *arraySize; word++) {
    int ch = 0;
    while (ch < strlen(pointerToArrayOfStrings[word])) {
      pointerToArrayOfStrings[word][ch] = theString[ch];
    }
    ch+=2;
  }
  return pointerToArrayOfStrings;
}

这会立即给我分段错误。我对指针很新,所以我的方法是首先为数组分配“numberOfWords”字符指针的内存量。然后我为每个字符指针分配了相应单词的大小。之后,我用原始字符串中的字符填充了插槽。我不知道我错过了什么。

1 个答案:

答案 0 :(得分:0)

这些评论已经解决了你关于seg-faults等问题。但是既然你没有说它是你如何分裂字符串,我想建议看另一种方法。

请考虑以下步骤:

1)通过字符串计算白色空间(单词)的出现次数并跟踪找到的最长单词 2)知道count,最长的单词,你就拥有了分配内存所需的内容。这样做。
3)在for循环中,使用 strtok() 和分隔符:\n\t等来标记字符串。<登记/> 4)使用 strcpy() (也在循环中)将每个标记转移到字符串数组中。
5)返回数组。使用数组。释放所有分配的内存。

执行以下步骤的示例代码:

char** splitString(const char theString[], int *arraySize);
char ** create_str_array(int strings, int longest) ;

int main(void)
{
    int size;
    char ** string = splitString("here is a string", &size);

    return 0;
}

char** splitString(const char theString[], int *arraySize) 
{
    *arraySize = strlen(theString) + 1; //Points to the number of words in the string.
    char *tok;
    char *dup = strdup(theString);//create copy of const char argument

    char** pointerToArrayOfStrings = NULL;
    int characters = 0;
    int len = 0, lenKeep = 0, wordCount = 0, i;

    /// get count of words and longsest string
    for(i=0;i<*arraySize;i++)
    {
      if((!isspace(theString[i]) && (theString[i])))
      {
          len++;
          if(lenKeep < len)
          {
              lenKeep = len;
          }
      }
      else
      {
        wordCount++;
        len = 0;
      }
    }

    /// create memory. (array of strings to hold sub-strings)
    pointerToArrayOfStrings = create_str_array(wordCount, lenKeep);
    if(pointerToArrayOfStrings)// only if memory creation successful, continue
    {
        /// parse original string into sub-strings
        i = 0;
        tok = strtok(dup, " \n\t");
        if(tok)
        {
            strcpy(pointerToArrayOfStrings[i], tok);
            tok = strtok(NULL, " \n\t");
            while(tok)
            {
                i++;
                strcpy(pointerToArrayOfStrings[i], tok);
                tok = strtok(NULL, " \n\t"); 
            }
        }
    }

    /// return array of strings
    return pointerToArrayOfStrings;
}

char ** create_str_array(int strings, int longest)
{
    int i;
    char ** a = calloc(strings, sizeof(char *));
    for(i=0;i<strings;i++)
    {
        a[i] = calloc(longest+1, 1);
    }
    return a;
}