Je suis encore nouveau dans la programmation en C. Je suis désolé si ce genre de question a déjà été posé, je ne savais pas vraiment quoi chercher exactement.

En tant qu'exercice, je programme un dictionnaire. L'utilisateur doit être en mesure d'ajouter, d'imprimer et de supprimer des mots à cette étape de l'exercice. Les mots sont stockés dans un tableau de pointeurs de caractères appelé «dict». La fonction «removeWord» doit s'assurer que le mot à supprimer est remplacé par le dernier mot du tableau «dict». Ainsi, le dernier mot doit être copié dans l'élément à supprimer, puis le dernier élément doit être supprimé (c'est-à-dire attribuer la valeur NULL à). Lorsque le mot à supprimer est le dernier mot du tableau «dict», il doit également être supprimé.

Le programme s'arrête quand un mot du tableau «dict» est supprimé à l'exception du dernier du tableau. Lorsqu'un mot à l'exception du dernier est supprimé, je veux attribuer la valeur NULL au dernier élément.

J'espère que ma question est claire. J'apprécie vraiment toute aide que vous pouvez fournir.

int numberOfWordsInDict(char **dict)
{
    int i,cnt=0;
    for(i=0;i<10;i++)
    {
        if(dict[i]!=NULL)
        {
            cnt++;
        }
    }
    return cnt;
}

void addWord(char **dict, char *word)
{
    int i=0;
    if(numberOfWordsInDict(dict)==10)
    {
        printf("Dictionary is already full!\n");
    }
    int k=numberOfWordsInDict(dict);
    dict[k]=(char*)malloc((strlen(word)+1)*sizeof(char));

    strcpy(dict[k],word);
}


void printDict(char **dict)
{
    int i=0;
    printf("Dictionary:\n");
    if(numberOfWordsInDict(dict)==0)
    {
        printf("The dictionary is empty.\n");

    }else
    {
        for(i=0;i<10;i++)
        {
        printf("- %s\n", dict[i]);
        }
    }
}

void removeWord(char **dict, char *word)
{
    int i,j=0;
    int swapped=0;
    j=numberOfWordsInDict(dict);
    for(i=0;i<j;i++)
    {
        if(strcmp(dict[i],word)==0 && swapped==0)
        {
        swapped=1;
        //strcpy(dict[i],dict[j-1]);
        dict[j-1] = NULL;
        }
    }

}

À dict [j-1] l'erreur se produit.

int main()
{
    char wordToBeAdded[36]={};
    char wordToBeRemoved[36]={};
    char *dict[10]={};
    char operation;

    while(1)
    {
        printf("Command (a/p/r/q): ");
        scanf(" %c", &operation);

        switch(operation)
        {
            case 'a':
                printf("Add a word: ");
                scanf(" %s", &wordToBeAdded);
                addWord(dict,wordToBeAdded);
                break;

            case 'p':
                printDict(dict);
                break;

            case 'r':
                printf("Remove a word: ");
                scanf(" %s", &wordToBeRemoved);
                removeWord(dict,wordToBeRemoved);
                break;

            case 'q':
                return 0;
        }
    }
}
0
Christiaan de Leijer 10 août 2017 à 19:06

2 réponses

Meilleure réponse

Le problème est que vous accédez au dernier élément de votre dict après qu'il a été supprimé. Lorsque vous accédez au dernier élément du dict pour le comparer au mot, il a déjà été défini sur null. Comme l'a commenté Weather Vane, vous pouvez vous casser lorsque vous trouvez le mot. Cela vous empêcherait d'accéder à ce dernier élément lorsqu'il a été supprimé.

void removeWord(char **dict, char *word)
{
    int i,j=0;
    int swapped=0;
    j=numberOfWordsInDict(dict);
    for(i=0;i<j;i++)
    {
        if(strcmp(dict[i],word)==0 && swapped==0)
        {
            swapped=1;
            //strcpy(dict[i],dict[j-1]);
            dict[j-1] = NULL;
        }
    }

}

Ainsi, lorsque i = j-1 if(strcmp(dict[i],word)==0 && swapped==0), cela essaiera de déréférencer le pointeur que vous venez de mettre à null.

1
Robert Derber 10 août 2017 à 16:59

Le problème est lorsque vous parcourez la table et essayez de lire à partir du pointeur avec la valeur NULL.

Lorsque vous supprimez le dernier mot, vous n'y arriverez jamais. Mais si vous ne supprimez pas le dernier lorsque vous parcourez le tableau, vous le supprimez.

Je ne vais pas changer la logique de votre code (et ne pas vérifier si elle fait ce que le nom de la fonction promet) - il suffit de nettoyer l'utilisation du pointeur en ajoutant la vérification si ce n'est pas NULL

void printDict(char **dict)
{
    int i=0;
    printf("Dictionary:\n");
    if(numberOfWordsInDict(dict)==0)
    {
        printf("The dictionary is empty.\n");

    }else
    {
        for(i=0;i<10;i++)
        {
        if(dict[i] != NULL) printf("- %s\n", dict[i]);
        }
    }
}


void removeWord(char **dict, char *word)
{
    int i,j=0;
    int swapped=0;
    j=numberOfWordsInDict(dict);
    for(i=0;i<j;i++)
    {
        if(dict[i] != NULL) 
           if(strcmp(dict[i],word)==0 && swapped==0)
           {
           swapped=1;
           //strcpy(dict[i],dict[j-1]);
           free(dict[j-1];
           dict[j-1] = NULL;
        }
    }

}
-1
P__J__ 10 août 2017 à 16:47