I am trying to make a word search game in C, of which a user will guess/input a word and the program will check if the word is existing and valid.
How can I check if the word inputted by a user is already printed/inputted? I'm really confused if what variable/s to compare, or if I need to create a function for that.
char guessed[], is a global array.
bool isAdded(char *token){
int i = 0;
while(guessed[i] != NULL){
if(strcmp(guessed[i], token) == 0){
return true;
}
i++;
}
return false;
}
main
while (1) {
printf("\n[GM: Find a word]> ");
if (!fgets(word, sizeof word, stdin)) {
break;
}
word[strcspn(word, "\n")] = '\0';
if (isAdded(word)) {
printf("[GM: Word already guessed]");
} else {
if (ifExist(matrix, word) && checkDictionary(dictionary, dict_len, word)) {
printf("[GM: Found it]\n");
}
else if (ifExist(matrix, word)) {
printf("[GM: It's not in the dictionary]\n");
}
else if (strcmp(word, "quit") == 0) {
break;
} else {
printf("[GM: Not found, please try again]\n");
}
}
}
}
The most basic solution is to add an array where past words are stored, and then search through it every time a word is queried to see if it is a repeat word. I'll repost the entire code you posted first: in the future, when you update your post please don't nuke the full example. You did the right thing by pasting the entire code, because there's something I want to touch on. All the changes are made in
main()
. The solution is a basic circular array that tramples past entries after it has reached its cap.Now to talk about a mistake you've made that's unrelated to the question you've asked, but is very important in terms of code correctness. The offending code is
combined with
Simply explained, the variable
dictionary
is originally declared as an array of pointers, and then cast to a pointer to pointer(s), but is initialized with string literals. This last point causes problems. I decided to go through the strings byte by byte, so to make the result more readable I've cleaned up the output by replacing null terminators with space so it can be seen as one string:one two two three three four four five five six six
Wait, what? Why are the words repeated? This is when you know something just isn't right. To be honest I don't know exactly why this happens, but it's really fucked. The issue is that you are declaring an array of pointers, but initializing it with string literals. In my opinion, C should not allow that to compile at all, but it does. What seemingly happens is that it allocates the string literals somewhere else in memory and gives you a pointer there, meaning that the difference between the address of is huge. One example is 0x0059(...) versus 0x7fff(...). So each element of
dictionary
is a pointer to one of these.Now, what you are doing in
checkDictionary()
with the for loop iterating over the pointer as an array is not advised, as you can't do that generally and have it be correct. What happens is that every increment of the index moves the memory access by 8 bytes (on 64-bit systems, which I'm assuming you're using. I don't even want to think about how this would work in 32-bit). IFdictionary
was initialized the way I think you wanted it to be with each word one after another in memory with no repeats this would not work, as words would be skipped. However, as "luck" would have it, the repeats are structured so that they don't interfere, and the way you iterate ends up working. But it is not right, and that sort of thing is guaranteed to blow up eventually with extremely annoying crashes and horrendous bugs.The fix is to just make
dictionary
achar**
orchar[][]
like you did with the matrix. In the former case you'll have to malloc each and every word but also be able to dynamically add to it, whereas the latter you'll have to specify each character and you'll end up using more memory as each entry will have to be homogenized to the largest string literal.