我正在尝试用C制作一个单词搜索游戏,用户将猜测/输入一个单词,程序将检查该单词是否存在和有效。
如何检查用户输入的单词是否已打印/输入?如果要比较什么变量,或者是否需要为此创建一个函数,我真的很困惑。
char猜测[],是一个全局数组。
bool isAdded(char *token){
int i = 0;
while(guessed[i] != NULL){
if(strcmp(guessed[i], token) == 0){
return true;
}
i++;
}
return false;
}
主
while (1) {
printf("n[GM: Find a word]> ");
if (!fgets(word, sizeof word, stdin)) {
break;
}
word[strcspn(word, "n")] = ' ';
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");
}
}
}
}
最基本的解决方案是添加一个存储过去单词的数组,然后在每次查询单词时对其进行搜索,看看它是否是重复单词。我会先转发你发布的全部代码:将来,当你更新你的帖子时,请不要破坏完整的例子。你粘贴了整个代码,这是正确的,因为我想触及一些东西。所有的更改都是在main()
中进行的。解决方案是一个基本的圆形数组,在达到上限后践踏过去的条目。
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#define SIZE 10 // row and column size
#define MAX 40 // word size
// Function to check if a word exists in the board
// starting from the first match in the board
// index: index till which pattern is matched
// i, j: current position in 2D array
bool adjacentSearch(char matrix[SIZE][SIZE], const char *find, int i, int j, int index) {
// pattern matched
if (find[index] == ' ')
return true;
// out of bounds
if (i < 0 || j < 0 || i >= SIZE || j >= SIZE || matrix[i][j] != find[index])
return false;
// marking this cell as visited
matrix[i][j] = '*';
// finding subpattern in 4 directions
bool found = (adjacentSearch(matrix, find, i + 1, j, index + 1) ||
adjacentSearch(matrix, find, i - 1, j, index + 1) ||
adjacentSearch(matrix, find, i, j - 1, index + 1) ||
adjacentSearch(matrix, find, i, j + 1, index + 1));
// marking this cell
// as unvisited again
matrix[i][j] = find[index];
return found;
}
// Function to check if the word exists in the board or not
bool ifExist(char matrix[SIZE][SIZE], const char *find) {
int len = strlen(find);
// if total characters in matrix is
// less then pattern length
if (len > SIZE * SIZE)
return false;
// traverse in the board
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (adjacentSearch(matrix, find, i, j, 0)) {
return true;
}
}
}
return false;
}
// Function to check if the word is in the dictionary
int checkDictionary(char **arr, int len, char *target) {
for (int i = 0; i < len; i++) {
if (strncmp(arr[i], target, strlen(target)) == 0) {
return true;
}
}
return false;
}
// Prints the board
void printBoard(char matrix[SIZE][SIZE]) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
printf(" %c ", matrix[i][j]);
}
printf("n");
}
}
void asdf(char* a) {
int k = 2;
return;
}
// Driver code
int main() {
char previous[SIZE][MAX];
int indexOfPrevious = 0;
char *dictionary[] = {"one", "two", "three", "four", "five", "six"};
int dict_len = sizeof dictionary / sizeof dictionary[0];
asdf(dictionary[0]);
char word[MAX], matrix[SIZE][SIZE] = {{'r', 'h', 'y', 't', 'h', 'm', 'y', 'o', 'n', 'e'},
{'j', 'e', 'p', 'u', 'o', 'o', 'f', 'u', 'o', 'l'},
{'r', 'e', 'n', 'd', 'e', 'o', 'i', 'e', 'l', 'c'},
{'o', 'p', 'e', 'e', 't', 'h', 'r', 'e', 'e', 'j'},
{'d', 'y', 'l', 'v', 'p', 'p', 'h', 'e', 't', 'p'},
{'h', 'e', 's', 'i', 'x', 'o', 'u', 'n', 'w', 'e'},
{'f', 'v', 'm', 'f', 'o', 'x', 'd', 'k', 'o', 'v'},
{'f', 'o', 'r', 'o', 's', 't', 'u', 'e', 'o', 'i'},
{'g', 'a', 'l', 'g', 'o', 'w', 'b', 'y', 'p', 'a'},
{'h', 'e', 'l', 'l', 'o', 'f', 'o', 'u', 'r', 'd'}};
printBoard(matrix);
while (1) {
Start:
printf("n[GM: Find a word]> ");
if (!fgets(word, sizeof word, stdin)) {
break;
}
word[strcspn(word, "n")] = ' ';
if (strcmp(word, "quit") == 0) {
break;
}
int repeatEntry = 0;
for (int i = 0; i < indexOfPrevious; i++) {
int Result = strncmp(previous[i], word, MAX);
if (!Result) {
repeatEntry |= 1;
// Insert what you want to do if a word is re-entered here
}
}
if (!repeatEntry) {
indexOfPrevious %= SIZE;
memcpy(previous[indexOfPrevious++], word, MAX);
}
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 {
printf("[GM: Not found, please try again]n");
}
}
return 0;
}
现在来谈谈你犯的一个错误,这个错误与你问的问题无关,但在代码正确性方面非常重要。违规代码是
char *dictionary[] = {"one", "two", "three", "four", "five", "six"};
与结合
int checkDictionary(char **arr, int len, char *target) {
for (int i = 0; i < len; i++) {
if (strncmp(arr[i], target, strlen(target)) == 0) {
return true;
}
}
return false;
}
简单地解释一下,变量dictionary
最初被声明为指针数组,然后被强制转换为指向指针的指针,但使用字符串文字进行初始化。最后一点会引起问题。我决定一个字节一个字节地遍历字符串,所以为了使结果更可读,我通过用空格替换空终止符来清理输出,这样它就可以被看作一个字符串:
one two two three three four four five five six six
等等,什么?为什么单词重复?这是当你知道有些事情不对劲的时候。老实说,我不知道为什么会发生这种事,但这真的很糟糕。问题是,您声明的是一个指针数组,但使用字符串文字初始化它。在我看来,C根本不应该允许编译它,但它确实允许。似乎发生的是,它将字符串文字分配到内存中的其他地方,并在那里给您一个指针,这意味着的地址之间的差异很大。一个例子是0x0059(…(与0x7fff(…(。因此,dictionary
的每个元素都是指向其中一个的指针。
现在,不建议您在checkDictionary()
中使用for循环将指针作为数组进行迭代,因为您通常无法做到这一点,并且不能使其正确。发生的情况是,索引的每一个增量都会将内存访问量移动8个字节(在64位系统上,我假设您正在使用它。我甚至不想考虑在32位系统中如何工作(。如果dictionary
按照我认为您希望的方式初始化,在内存中每个单词一个接一个,没有重复,这将不起作用,因为单词将被跳过。然而,正如"幸运"所说,重复的结构不会干扰,迭代的方式最终会起作用。但这是不对的,这种事情最终肯定会爆发出极其令人讨厌的崩溃和可怕的错误。
修复方法是将dictionary
设置为char**
或char[][]
,就像对矩阵所做的那样。在前一种情况下,您必须对每个单词进行malloc,但也可以动态添加到其中,而在后一种情况中,您必须指定每个字符,最终将使用更多的内存,因为每个条目都必须统一为最大的字符串文字。