删除字符串数组项并将其余项移动到C中

3

第一个问题是:使用数组是否有可能实现?我看到一些建议说最好使用列表而不是数组,但我的程序必须使用数组。

`for(j=0;j<size_array;j++){
 if(strcmp(a[j],input)==0){
    strcpy(a[j], "\0");
    a[j] = a[j-1];
    size_array--;
}
}`

我尝试过以下方法,得到了如下结果:

a[0] = "apple"

a[1] = "banana"

a[2] =         //removed item

a[3] = "orange"

有没有办法将“orange”移动到a[2]的位置,像这样:
a[0] = "apple"

a[1] = "banana"

a[2] = "orange"

感谢您的预先支持。
谢谢。

我不确定这是否是 XY 问题。您想弹出该位置,还是要修复您发布的 for 循环,以便将所有内容从空位移动? - Jacqlyn
3个回答

1
您正在寻找 memmove 函数:
#include <string.h>
.
.
.
remove_item(a, offset);

// memmove(destination, source, nbytes)
memmove(a + offset, a + (offset + 1), (a_len - (offset + 1)) * sizeof a[0]);

例如,如果您有4个项目,并且删除第1个项目(项目编号为0..3),则应执行以下操作:
// memmove(a + 1, a + (1+1), (4 - (1+1)) * sizeof a[0]);
memmove(a + 1, a + 2, 2 * sizeof a[0]);

在窄字符串字面值的情况下,可以省略对sizeof位的乘法运算,因为sizeof(char)始终为1,但出于完整性考虑,我将其包含在内。
您也可以使用循环自行完成此操作,并且我强烈建议在有时间时尝试这样做。它从源到目标执行简单的浅复制,注意要小心处理重叠的内存范围。请参阅任何良好的C参考资料以获取有关该函数的更多信息,因为它是标准C库的一部分。

1
我怀疑你展示的代码输出结果与你所展示的不同,它应该输出:
a[0] = "apple"
a[1] = "banana"
a[2] = "banana"
a[3] = "orange"

无论如何...您实际上只需要找到要删除的字符串的索引,然后开始将其后面的字符串向后移动一步。完成后,可以减小数组的大小。
由于您能够执行a[j] = a[j-1],我假设您正在使用指针数组。在这种情况下,没有必要使用strcpy(a[j], "\0");,只需将下一个元素向后移动一步即可。如果要删除的字符串是动态分配的,则可能需要释放其内存。
以下是一个示例,可以打印出您期望的输出:
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

int main(int argc, char** argv)  
{ 
    int size = 0, capacity = 10, i;
    char** array = malloc(sizeof(char*) * capacity);
    array[0] = strdup("apple");
    array[1] = strdup("banana");
    array[2] = strdup("pear");
    array[3] = strdup("orange");
    size = 4;

    for(i = 0; i < size; i++) {
        printf("%s\n", array[i]);
    }

    for(i = 0; i < size; i++) {
        if(strcmp(array[i], "pear") == 0) {
            free(array[i]);
            break;
        }
    }
    for(; i < size; i++) {
        array[i] = array[i+1];
    }
    size--;


    printf("\n");

    for(i = 0; i < size; i++) {
        printf("%s\n", array[i]);
    }

    return 0;  
} 

这将打印:

apple
banana
pear
orange

apple
banana
orange

0

很遗憾,在C语言中你不能直接弹出那个点。如果你使用链表,就像你说的那样,你就可以了。

看起来你的代码有错误。因为你正在增加j并减小size_array,所以你最终不会触及size_array/2+1之后的元素。

另外,看起来你正在使用你没有发布的代码,这使得调试变得混乱,但是你想要的代码大致如下:

for(j=0;j<size_array-1;j++){
    if(strcmp(a[j],input)==0){
       strcpy(a[j], a[j+1]);
}

请注意,size_array 要小一个单位,因为您不希望检查列表末尾,因为这没什么作用。此外,对于字符串,您不能使用“=”运算符,必须使用 strcpy 或手动完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接