我正在创建一个猜词游戏,它逐行读取文本文件,直到找到一个随机单词并将其存储在字符串中(word
)。然后用户输入字母,直到存储的单词的所有字母都显示出来。
到目前为止,它工作得很好,但每次读取第一个单词时,一些未知字符都会存储在 char word[20]
的开头。
请注意,我使用 C 移动应用程序,我认为它使用 clang 6.0 编译器。那么错误是来 self 的代码还是来自他们的应用程序? (我喜欢)。
这是完整、更清晰的代码:
//guess the right word
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define NB_OF_WORDS 3 //number of words in text file
main() {
char begin, word[20] = { 0 }, guessedletter;
int num, rightletter, success;
int i = 0;
int show[20] = { 0 };//shown letters
FILE *ressource = NULL;
srand(time(NULL));
if ((ressource = fopen("ressource.txt", "r")) == NULL) {
fprintf(stderr, "Error ressource.txt");//open in read only mode
exit(EXIT_FAILURE);
}
printf("Welcome to Word Guess, a word guessing contest.\n"
"You have to find the letters of a word and guess what word it is.\n"
"Begin? (y/n)\n");
while ((begin = getchar()) == 'y') { //game loop
/*reinitializations*/
fseek(ressource, 3, SEEK_SET);//replaces rewind(ressource)
success = FALSE;
rightletter = 0;
num = 0;
num = rand() % NB_OF_WORDS; //random number between 0 and NB-1
for (i = 0; i < 20; i++) {
show[i] = FALSE;
word[i] = 0;
}
i = 0;
/*end of reinitializations*/
while (i <= num) {//reads line by line until random word is stored
if (fgets(word, 20, ressource) == NULL) {
fprintf(stderr, "fgets did not work");
exit(EXIT_FAILURE);
}
i++;
}
printf("%s", word);//here is just for testing if the read word is well read. Which isn't the case if num=0
for (i = 0; i < 20; i++)
if (word[i] == '\n')
word[i] = '\0';//adds zero character to show where the string ends
while (!success) { //guessing loop
printf("\nWrite a letter: ");
scanf("%c", &guessedletter);
printf("\n");
for (i = 0; word[i] != '\0'; i++) { //compares entered letter to letter from string. If they match...
if (word[i] == guessedletter) {
if (!show[i])
rightletter++;//avoids letters entered twice from increasing count
show[i] = TRUE;
}
if (show[i])
printf("%c", word[i]);//...a letter is revealed...
else
printf("*");//else it stays hidden
}
if (rightletter == strlen(word))
success=TRUE;//if all the right letters found (same number of letters found as number of letters in the words) you win
}
printf("\nCongratulations you have won!\nDo you want to replay? (y/n)");
getchar();//clears newline character
}
fclose(ressource);
return 0;
}
当 num=0 时,我在打印的单词之前得到一个奇怪的符号,就好像文本文件的第一个字符不应该在那里......
此外,在猜谜游戏中,如果要猜测的单词(word[20])“令人讨厌”,可以说它是“ressource.txt”(num=0)中的第一个单词。一旦我猜出了所有字母,这个词就会像这样打印在屏幕上:***烦人。列表中的任何其他单词都不会发生这种情况。
我是这个网站的新手,并通过手机发帖...对于任何错误,我们深表歉意。
编辑:删除了 fgets 的 fgetc。如果 fgets 读取第一行,仍然会得到几个未知字符。
编辑2:添加整个代码,将mot[20]翻译成word[20],添加错误测试
编辑3:替换倒带(资源);通过 fseek(资源, 3, SEEK_SET);解决了问题。这意味着文本文件的开头确实存在三个未知字符
最佳答案
发布的代码中有多个问题:
- 您只发布了代码片段,函数的其余部分可能会导致无法根据您发布的内容进行分析的问题。请将完整的代码发布到显示问题的最小程序中。
- 您不会在
while
循环中测试文件结尾。如果您尝试跳过的行数多于文件中存在的行数,则此循环将无限期地运行。 - 您不测试
fgets()
的返回值:如果您偶然在前面的while
循环中跳过了文件的完整内容,fgets ()
将失败并返回NULL
,使mot
处于未确定状态,从而导致后续printf
出现意外行为。<
编辑:修改后的代码仍然不检查fgets()
的返回值。
编辑:感谢您发布完整的代码,但是以这种方式修改问题会使这个答案和评论变得无关紧要。
您的字典文件 ressource.txt
似乎以 BOM (Byte Order Mark) 开头以 UTF-8 编码。我猜测它包含法语单词,其中包括一些带重音字母的单词,例如 reculées 和 encodeées...您的文本编辑器将其以 UTF-8 编码保存,并带有额外的代码点在开始时其他程序可以轻松确定此编码。问题是你的程序不处理 UTF-8。它假设从 stdin
读取的每个字节代表一个字符。它可能会偶然匹配一些带有重音字母的单词,但更有可能找不到它们。
关于c - fgets 存储文本文件中的未知数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51460104/