C语言 从数组中删除单词

toiithl6  于 2023-03-07  发布在  其他
关注(0)|答案(2)|浏览(140)

在这个程序中你可以添加,打印和删除单词。我有一个问题与delete()函数。例如,如果我添加以下单词:coconutmangobananaapple。如果我想删除mango,它会删除mango,然后将apple更改为banana,所以删除后得到的结果是coconutbananabanana。我在这里做错了什么?不要对原始代码做太多更改,谢谢!

#include <stdio.h>
#include <string.h>

#define MAX 20

void add(char word[][MAX], int *nrOfWords);
void printWord(char word[][MAX], int nrOfWords);
void delete(char word[][MAX], int *nrOfWords);

int main() {
    char word[10][MAX];
    int nrOfWords = 0, choice; 

    while (1) {
        printf("(1)add word(2)print words(3)delete: ");
        scanf("%d", &choice);
        switch (choice) {     
          case 1:
            add(word, &nrOfWords);
            break;
          case 2:
            printWord(word, nrOfWords);
            break;
          case 3:
            delete(word, &nrOfWords);
            break;
        }
    }
    return 0;
}

void add(char word[][MAX], int *nrOfWords) {
    while (*nrOfWords < 10) {
        printf("Add word: ");
        scanf("%s%*c", &word[*nrOfWords]); 

        if (strcmp(word[*nrOfWords], "q") == 0)
            break;
        (*nrOfWords)++;
    }
}

void printWord(char word[][MAX], int nrOfWords) {
    for (int i = 0; i < nrOfWords; i++) {
        printf("%s, ", word[i]);
    }
    printf("\n");
}

void delete(char word[][MAX], int *nrOfWords) {
    char deleteWord[MAX];

    while (1) {
        printf("Word to delete:");
        scanf("%s%*c", &deleteWord);
        if (strcmp(deleteWord, "q") == 0)
            break;    
        for (int i = 0; i < *nrOfWords - 1; i++)
            if (strcmp(word[i], deleteWord) == 0) {
                strcpy(word[i], word[i + 1]);     
                (*nrOfWords)--;
            }
    }
}
iq0todco

iq0todco1#

delete的主要问题是,在删除一个单词后,它需要向前移动它后面的所有单词来填补差距。但在发布的代码中,它只移动紧跟在它后面的单词。在查找单词时,它也会过早地停止,如果它是最后一个单词,它就找不到了。
此外,读取一个字的scanf调用传递了错误的参数类型。它们需要传递char *值。这会导致编译时警告(确保启用了警告,然后修复它们)。
第一个不正确的scanf调用位于add中。它应该是:

scanf("%s%*c", word[*nrOfWords]);

例如,卸下&
第二个不正确的scanf调用位于delete中,其中存在逻辑错误。以下是delete函数的更正版本:

void delete(char word[][MAX],int *nrOfWords){
    char deleteWord[MAX];
    while(1){
        printf("Word to delete:");
        scanf("%s%*c",deleteWord);
        if(strcmp(deleteWord,"q")==0)break;
        for(int i=0; i<*nrOfWords; i++) {
            if(strcmp(word[i],deleteWord)==0){
                (*nrOfWords)--;
                for (int j=i; j<*nrOfWords; j++) {
                    strcpy(word[j],word[j+1]);
                }
                i--;
            }
        }
    }
}

这允许删除任何单词,并将 * 所有 * 后面的单词(如果有的话)复制到下一个单词。

xt0899hw

xt0899hw2#

要从数组中删除匹配的单词,必须将所有剩余的单词下移一个位置。这可以通过嵌套循环来完成:

void delete(char word[][MAX], int *nrOfWords) {
    char deleteWord[MAX];

    for (;;) {
        printf("Word to delete:");
        if (scanf("%19s%*c", deleteWord) != 1 || !strcmp(deleteWord, "q"))
            break;    
        for (int i = 0; i < *nrOfWords;) {
            if (strcmp(word[i], deleteWord) == 0) {
                (*nrOfWords)--;
                for (int j = i; j < *nrOfWords; j++) {
                    strcpy(word[j], word[j + 1]);
                }
            } else {
                i++;
            }
        }
    }
}

注意i如何仅在word[i]deleteWord不匹配时递增,否则在扫描中将跳过后面的字。
上面的方法对于有很多重复项的大型数组效率不高。下面是一个元素移动较少的替代方法:

void delete(char word[][MAX], int *nrOfWords) {
    char deleteWord[MAX];

    for (;;) {
        int i, j;

        printf("Word to delete:");
        if (scanf("%19s%*c", deleteWord) != 1 || !strcmp(deleteWord, "q"))
            break;    
        for (i = j = 0; i < *nrOfWords; i++) {
            if (strcmp(word[i], deleteWord) != 0) {
                if (i != j) {
                    strcpy(word[j], word[i]);
                }
                j++
            }
        }
        *nrOfWords = j;
    }
}

相关问题