从C中的字符串数组中删除字符串(即,从2D数组中的项目中删除项目)

时间:2020-08-07 12:21:29

标签: arrays c string

所以我有一个包含重复项的字符串数组。我的总体目标是删除重复项并相应地调整数组大小。到目前为止,我最好的方法是使用memmove()函数。

我当前的测试方法是遍历数组并扫描每个项目。如果遇到一个字符串不止一次,那么我将使用memmove()用列表中的下一个项目覆盖重复项。列表中的每一项也将使用memmove()在数组中上移一位。然后,我将调整整个数组的大小,以删除数组末尾的空内存位置。

我已经这样声明了数组:

char source[43][20];

该数组只是一个城市列表(我仅包括了前6个用于演示的城市):

York
Leeds
Liverpool
Manchester
Reading
Oxford

我设法用下面的代码覆盖了第一个元素和第二个元素:

memmove(&(source[0][0]), &(source[1][0]), strlen(source[1]) * sizeof(char));

提供此输出:

Leeds
Leeds
Liverpool
Manchester
Reading
Oxford

但是当我尝试使用此代码覆盖第二个元素上的第三个元素时:

memmove(&(source[1][0]), &(source[2][0]), strlen(source[2]) * sizeof(char));

我得到以下输出:

Leeds
Liverpooφu
Liverpool
Manchester
Reading
Oxford

如您所见,利物浦无法正常工作。目前,我目前也不知道如何调整数组的大小,因此,我将不胜感激。感谢任何帮助人员:)。

3 个答案:

答案 0 :(得分:3)

进行复制时,不会复制终止的空字节。这意味着复制之后发生的任何垃圾都会被当作字符串的一部分读取。

由于数组元素的大小固定,因此只需复制整个子数组即可:

memcpy(source[0], source[1], sizeof(source[0]));

如果要移动多个元素:

memmove(source[0], source[1], sizeof(source[0]) * num_to_move);

答案 1 :(得分:0)

复制字符串时,您忘记了零终止字符。您需要strlen(...) + 1复制包含零个终止字符的字符串。

sizeof(char)可以省略-char总是1个字节,sizeof(char)总是1个字节。

这里不需要使用memmove,假设strlen(source[2]) + 1 < 20,则source[1], source[1] + strlen(source[2])source[2], source[2] + strlen(source[2])]会干扰存储区域。然后memcpy即可。但就此而言,只需strcpy个字符串。

strcpy(source[0], stource[1]);
strcpy(source[1], stource[2]);
// etc...

如果您不关心复制的额外字节,则可以一次性移动所有字符串,例如:

memmove(&source[0], &source[1], sizeof(source) - 1 * sizeof(*source));

答案 2 :(得分:0)

请注意,您无法调整数组大小。为了能够使用realloc,您可以执行以下操作:

char (*source)[20] = malloc(sizeof *source * 43);

这将为您提供一个指向20个字符的数组的指针,然后为43个此类数组分配内存。以后可以重新分配。像这样:

char (*source)[20] tmp = realloc(source, sizeof *source * size);
if(tmp)
    source = tmp;
else
    // Handle error

请注意,char (*source)[20]char *source[20]完全不同。后者是20个指针的数组。

还要注意,sizeof可能有些棘手。上面的方法有效,但是如果您使用char **source而不是char (*source)[20],则必须对其进行修改。

为了完整起见,即使其他人提到过,您的问题也在于您没有复制\0字符。最简单的解决方案是使用strcpy,但是strncpy更安全。

strncpy(source[0], source[1], 20);