每次运行这个程序时我都会遇到段错误,但我不明白为什么

时间:2017-09-17 03:17:52

标签: c++ arrays segmentation-fault c-strings

我有一个函数,它接受用户输入的字符串,并使用动态分配的二维数组将其拆分为单个单词。单词由分隔符分隔,分隔符用作一个单词结束而另一个单词开始的指示符。

这是我的代码:

int countWords(const char * sentence, char * delims)
{
       int wordsInArray = 0;
       int count = 0;
       while(*(sentence + count) != '\0')
       {
           if(*(sentence + count) == *delims && *(sentence + count + 1) != *delims)
           {
                 wordsInArray++;
           }
           if(*(sentence + count + 1) == '\0')
           {
                 wordsInArray++;
           }
       count++;
       }
       return wordsInArray;
}

int getLength(const char * sentence)
{
      const char *p = sentence;
      while(*p != '\0')
      {
         p++;
      }
      return p-sentence;
}


char ** getWords(const char * sentence, int & wordcount)
{
      char delims[] = " .,\t?!";
      int sentenceLength = getLength(sentence);
      wordcount = countWords(sentence, delims);

      char ** words;
      words = new char *[wordcount];

      int length = 0;
      int count = 0;
      for (int a = 0; a < sentenceLength; a++)
      {
          if(*(sentence + a) != *delims)
          {
             length++;
          }

          else if ((*(sentence + a) == *delims && *(sentence + a + 1) != *delims) || *(sentence + a) == '\0')
          {
              *(words + count) = new char[length+1];
              for (int z = 0; z < length; z++)
              {
                   *(*(words + count) + z) = *(sentence + z);
              }
              length = 0;
              count++;
          }
      }
      return words;
}

但是,我的countWords函数没有正确计算字符串中的单词,我不知道为什么。

1 个答案:

答案 0 :(得分:0)

尝试更像这样的事情:

int indexOf(const char * sequence, char ch) {
    const char *p = sequence;
    while (*p != '\0') {
        if (*p == ch) {
            return p - sequence;
        }
    }
    return -1;
}

const char* findFirstOf(const char * sequence, const char *chars) {
    const char *p = sequence;
    while (*p != '\0') {
        if (indexOf(chars, *p) != -1)  {
            return p;
        }
    }
    return NULL;
}

const char* findFirstNotOf(const char * sequence, const char *chars) {
    const char *p = sequence;
    while (*p != '\0') {
        if (indexOf(chars, *p) == -1)  {
            return p;
        }
    }
    return NULL;
}

int countWords(const char * sequence, char * delims) {
    int count = 0;
    const char *p = sequence;
    do {
        p = findFirstNotOf(p, delims);
        if (p == NULL) break;
        ++count;
        p = findFirstOf(p, delims);
    }
    while (p != NULL);
    return count;
}

int getLength(const char * sequence) {
    const char *p = sequence;
    while (*p != '\0') {
        ++p;
    }
    return p-sequence;
}

char* dupString(const char * sequence, int length = -1) {
    if (length == -1) {
        length = getLength(sequence);
    }
    char *result = new char[length+1];
    for (int i = 0; i < length; ++i) {
        result[i] = sequence[i];
    }
    result[length] = '\0';
    return result;
}

char** getWords(const char * sequence, int & wordcount) {
    const char delims[] = " .,\t?!";
    int count = countWords(sequence, delims);
    char ** words = new char *[count];
    if (count > 0) {
        count = 0;
        const char *p = sequence;
        do {
            p = findFirstNotOf(p, delims);
            if (p == NULL) break;
            const char *q = findFirstOf(p, delims);
            if (q == NULL) {
                words[count++] = dupString(p);
                break;
            }
            words[count++] = dupString(p, q-p);
            p = ++q;
        }
        while (true);
    }
    wordcount = count;
    return words;
}

话虽如此,您使用new[]的事实意味着您正在使用C ++,因此您应该使用STL来简化生活:

#include <string>
#include <vector>

std::vector<std::string> getWords(const std::string & sequence) {
    const char delims[] = " .,\t?!";
    std::vector<std::string> words;
    std::string::size_type i = 0;
    do {
        i = sequence.find_first_not_of(delims, i);
        if (i == std::string::npos) break;
        std::string::size_type j = sequence.find_first_of(delims, i);
        if (j == std::string::npos) {
            words.push_back(sequence.substr(i));
            break;
        }
        words.push_back(sequence.substr(i, j-i));
        i = ++j;
    }
    while (true);
    return words;
}