使用定界符拆分文本?

Split text using delimiter?

我想创建一个用定界符分割字符串的函数。我知道已经有一个函数可以做这件事,但我想自己做。但它不能正常工作.

char** Engine::splitString(const char* text, char delimiter)
{

  char** splitted;  
  splitted = (char**)malloc(50 * sizeof(char*));
  for (int y = 0; y < 50; y++)
    splitted[y] = (char*)malloc((strlen(text) + 2) * sizeof(char));

  int delimiterPosition[50];
  int arrayLength = 0;
  int f = 0;
  int g = 0;
  for (int x = 0; x < strlen(text); x++)    
  {
    if (text[x] == delimiter)
    {
        delimiterPosition[f] = x;
        f++;
    }
  }

  for (int x = 0; x < 50; x++)
    if (delimiterPosition[x] > 0 )
        arrayLength++;


  while (g < arrayLength) {
     if (g == 0) {
        for (int y = 0; y < delimiterPosition[0]; y++)
        {
            splitted[g][y] = text[y];
        }
    }
    else if(g > 0)
    {
        for (int y = delimiterPosition[g - 1]; y < delimiterPosition[g] - delimiterPosition[g - 1]; y++)
        {
            splitted[g][y] = text[y];
        }
    }
    g++;
}
return splitted;
}

首先,我声明了一个二维字符数组-> 拆分。这是我应该将结果存储到的变量。然后我为它分配了一个内存..我想最多有50个字。之后我创建了整数数组。这用作分隔符位置的存储。我还在它下面为我的代码定义了一些变量。然后我遍历文本以查看是否有任何定界符.. 如果是,我想将它的位置存储到数组中的某个位置,从 0 开始。我遍历 delimiterPosition 的数组到我存储的位置。然后我做了一个简单的循环,使用 while 将所有字符带到分隔符的位置并将它们存储到 splitted[g][y] .. g 代表整个单词.. y 代表该单词中的字符。如果 g 大于零,我取一个分隔符的前一个位置,然后从前一个中减去当前位置..这就得到了第一个分隔符和下一个分隔符之间的距离..

这里的主要问题是第一个单词写对了,第二个单词不工作,但是当我尝试调用它时它后面有一些奇怪的字符..文本不知何故泄漏了吗?第二个根本没有存储?:

    char** strings = en.splitString("Hello;boy", ';');
    printf("%s", strings[1]);

第一个词:

第二个:

伙计们,有什么解决办法吗? :) 感谢您的任何评论。

这不会初始化内存:

 int delimiterPosition[50];

所以它的内容可能是随机的(并且它是未定义的,除非你先初始化它)。所以在这里:

 if (delimiterPosition[x] > 0 ) // Is potentially invalid if x >= f

轻松解决:

 int delimiterPosition[50] = {0};

此处可能溢出:

        delimiterPosition[f] = x;
        f++;

您没有验证 f 是否保持在正确的范围内(小于 50)。另一个简单的修复:

  size_t stringLen = strlen(text); // Don't need to recalculate this each time!
  for (int x = 0; f < 50 && x < stringLen; x++)    
  {
    if (text[x] == delimiter)
    {
        delimiterPosition[f] = x;
        f++;
    }
  }

这是您投诉的问题:


    for (int y = 0; y < delimiterPosition[0]; y++)
    {
        splitted[g][y] = text[y];
    }

您复制字符串。
但是您不向字符串添加终止符。因此,当您尝试打印它时,您会在末尾看到所有额外的字符。

    for (int y = 0; y < delimiterPosition[0]; y++)
    {
        splitted[g][y] = text[y];
    }
    splitted[g][y] = '[=16=]';  // Add string terminator.

对于第二个后续字符串,您遇到了空终止符问题。但是你也有问题,你正在复制字符串而不是开头。

        // After the first string the value of y in an offset into text only
        // So when used with `splitted[g]` you are offset from the beginning
        // if the string.
        splitted[g][y] = text[y];

你对字符串结尾的测试也是错误的:

记住你开始于:

int y = delimiterPosition[g - 1]

所以 y 是字符串的偏移量。所以当你增加它时,它总是一个偏移量而不是长度。

// So this test is wrong (you are using a length not an offset.
y < delimiterPosition[g] - delimiterPosition[g - 1]

让我们同时修复两者:

    int dstIndex = 0;
    for (int y = delimiterPosition[g - 1]; y < delimiterPosition[g]; y++, dstIndex++)
    {
        splitted[g][dstIndex] = text[y];
    }
    splitted[g][dstIndex] = '[=20=]';