kbim kbim - 1 month ago 10
C Question

remove element from pointer array in C

I'm trying to figure out why I cannot delete elements from the dict array. Could somebody help me out? The function removeWord is working as it is supposed to when removing the last added word, but not when trying to remove some other word.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUMBER_OF_WORDS 11

int clear(){
while(getchar()^'\n');
return 0;
}

int numberOfWordsInDict(char **dict){
int i = 0;
int c1 = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
if (dict[i] != 0){
c1++;
}
}
return c1;
}

void addWord(char **dict, char *word){
int c1 = numberOfWordsInDict(dict);
char *word1;
if (c1 >= 0 && c1 < 10){
word1 = (char*) malloc(sizeof(char)*(strlen(word)+1));
dict[c1] = word1;
strncpy(dict[c1], word, strlen(word));
dict[c1][strlen(word)] = '\0';
} else if (c1 >= 10){
printf("Dictionary is already full!\n");
}
}

void printDict(char **dict){
int i = 0;
int c1 = numberOfWordsInDict(dict);
printf("Dictionary:\n");
if (c1 == 0){
printf("The dictionary is empty.\n");
} else if (c1 > 0 && c1 <= 10){
while (dict[i] != NULL){
printf("- %s\n", dict[i]);
i++;
}
}
}

void removeWord(char **dict, char *word){
int i = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; i++){
if (strncmp(dict[i], word, strlen(word)+1) == 0){
dict[i] = 0;// can only delete the last element of dict properly.
break;
}
}
}

int main(){
char *dict[MAX_NUMBER_OF_WORDS] = {};
char word[1024] = {};
char command;

while(1){
printf("Command (a/p/r/q): ");
while(scanf("%s", &command) == 1){
break;
}
;
clear();

if (command == 'a'){ // add word
scanf("%[^\n]s", &word);
clear();
addWord(dict, word);
} else if (command == 'p'){ // print dict
printDict(dict);
} else if (command == 'r'){ // remove word
printf("Remove a word: ");
scanf("%[^\n]s", &word);
clear();
removeWord(dict, word);
} else if (command == 'q'){ // quit
break;
}
}

int i = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; i++){
free(dict[i]);
}

return 0;
}


example input:

a
dog
a
cat
a
apple


case 1:

r
apple
p
// output =
Dictionary:
- dog
- cat
a
uniform
p
// output =
Dictionary:
- dog
- cat
- uniform
// works fine


case 2

r
cat
p
// output =
Dictionary:
- dog
a
book
p
// output =
Dictionary:
- dog
// doesn't work as expected

Answer
#include <stdio.h>
#include <stdlib.h> 
#include <string.h>   
#define MAX_NUMBER_OF_WORDS 11

int clear(){
    while(getchar()^'\n');
    return 0;
}

int numberOfWordsInDict(char **dict){
    int c1 = 0;
    for(int i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
        if (dict[i] != 0){
            c1++;
        }
    }
    return c1;
}

int vacancy(char **dict){
    for(int i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
        if (dict[i] == 0){
            return i;
        }
    }
    return -1;
}

void addWord(char **dict, char *word){
    int c1 = vacancy(dict);//It is not possible to use the registration number as an additional index.

    if (-1 != c1){
        dict[c1] = malloc(strlen(word)+1);
        strcpy(dict[c1], word);
    } else {
        printf("Dictionary is already full!\n");
    }
}

void printDict(char **dict){
    int c1 = numberOfWordsInDict(dict);
    printf("Dictionary:\n");
    if (c1 == 0){
        printf("The dictionary is empty.\n");
    } else {
        for(int i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
            if(dict[i])
                printf("- %s\n", dict[i]);
        }
    }
}

void removeWord(char **dict, char *word){
    for(int i = 0; i < MAX_NUMBER_OF_WORDS; i++){
        if (strcmp(dict[i], word) == 0){
            free(dict[i]);//need free
            dict[i] = 0;// can only delete the last element of dict properly.
            break;
        }
    }
}

int main(){
    char *dict[MAX_NUMBER_OF_WORDS] = { NULL };
    char word[1024] = { 0 };//forbids empty initializer braces
    char command;

    while(1){
        printf("Command (a/p/r/q): ");
        scanf("%c", &command);//%s buffer over run
        clear();

        if (command == 'a'){        // add word
            scanf("%[^\n]", word);
            clear();
            addWord(dict, word);
        } else if (command == 'p'){  // print dict
            printDict(dict);        
        } else if (command == 'r'){  // remove word
            printf("Remove a word: ");
            scanf("%[^\n]", word);
            clear();
            removeWord(dict, word);
        } else if (command == 'q'){  // quit
            break;
        }
    }

    int i = 0;
    for (i = 0; i < MAX_NUMBER_OF_WORDS; i++){
        free(dict[i]);
    }

    return 0;
}