这是我遇到了一个非常有趣的问题。 我做了很多的堆栈溢出搜索,发现其他人有一些类似的问题。 所以我写了相应的我的代码。 我本来fscan()
和strcmp()
,但对我彻底失败。 所以其他职位建议fgets()
和strncmp()
并使用长度,并比较他们。
我试图调试什么我被打印出我的两个字符串的大小做。 我想,也许他们有/n
又在里面浮搞乱它(另一篇文章中谈到了这一点,但我不认为发生在这里)。 所以,如果大小是一样的,对于限制strncmp()
应该是相同的。 对? 只是为了确保他们理应被比较合适的。 现在,我知道,如果字符串是相同的,则返回0
,否则负与strncmp()
但它不工作。
这是我得到的输出:
perk
repk
Enter your guess: perk
Word size: 8 and Guess size: 8
Your guess is wrong
Enter your guess:
这里是我的代码:
void guess(char *word, char *jumbleWord)
{
size_t wordLen = strlen(word);
size_t guessLen;
printf("word is: %s\n",word);
printf("jumble is: %s\n", jumbleWord);
char *guess = malloc(sizeof(char) * (MAX_WORD_LENGTH + 1));
do
{
printf("Enter your guess: ");
fgets(guess, MAX_WORD_LENGTH, stdin);
printf("\nword: -%s- and guess: -%s-", word, guess);
guessLen = strlen(guess);
//int size1 = strlen(word);
//int size2 = strlen(guess);
//printf("Word size: %d and Guess size: %d\n",size1,size2);
if(strncmp(guess,word,wordLen) == 0)
{
printf("Your guess is correct\n");
break;
}
}while(1);
}
我从下面的建议更新它。 特别是经过学习之间的差异char *
作为指针和引用的东西作为一个字符串 。 然而,它仍然给了我同样的错误。
请注意, MAX_WORD_LENGTH
是在我的程序的顶部,使用的定义语句
#define MAX_WORD_LENGTH 25
sizeof(guess)
返回一个的大小char *
不是字符串的长度guess
。 你的问题是,你正在使用sizeof
来管理字符串长度。 C具有为字符串长度的函数: strlen
。
sizeof
被用来确定数据类型和数组的大小。 sizeof
只适用于在一个非常特殊的情况下琴弦-我不会去到这里-但即使是这样,一直使用strlen
与字符串长度工作。
你要决定你有多少个字符允许你的话。 这是你的游戏的属性,在游戏中即的话从来都不多于11个字符长。
所以:
// define this somewhere, a header, or near top of your file
#define MAX_WORD_LENGTH 11
// ...
size_t wordlen = strlen(word);
size_t guessLen;
// MAX_WORD_LENGTH + 1, 1 more for the null-terminator:
char *guess = malloc(sizeof(char) * (MAX_WORD_LENGTH + 1));
printf("Enter your guess: ");
fgets(guess, MAX_WORD_LENGTH, stdin);
guessLen = strlen(guess);
此外,还查看文档的fgets
并注意换行符保留在输入,所以你需要考虑的是,如果你想这两个词比较。 一个快速解决,这是只比较最多的长度word
,而不是长度guess
,所以: if( strncmp(guess, word, wordLen) == 0)
这种速战速决的问题是,它会通过无效输入,也就是说,如果word
是eject
,并guess
是ejection
,比较会通过。
最后,没有理由来分配内存为新guess
在循环的每次迭代,只需使用你已经分配的字符串。 你可以改变你的功能设置到:
char guess(char *word, char *jumbledWord)
{
int exit;
size_t wordLen = strlen(word);
size_t guessLen;
char *guess = malloc(sizeof(char) * (MAX_WORD_LENGTH + 1));
do
{
printf("Enter your guess: ");
// ...
使用strlen
,不是sizeof
。 此外,你不应该使用strncmp
这里,如果你的猜测是,这个词会误报匹配的前缀。 使用strcmp
。
正如其他人所指出的,使用strlen
不是sizeof
。 这虽然发生的原因,是一个基本概念C
这是从不同Java
。
Java
不给你访问的指针 。 不仅C
有一个指针,但他们的语言设计的基础 。 如果你不理解和正确使用指针C
那么事情就没有意义,你将有相当多的麻烦。
因此,在这种情况下, sizeof
被返回的大小char *
指针,它是(通常)4或8个字节。 你需要的是数据结构“的另一端”指针的长度。 这是strlen
封装为您服务。
如果你没有strlen
,你需要取消引用指针,然后步行串,直到找到空字节标记结束。
i = 1;
while(*guess++) { i++ }
之后, i
会牵着你的字符串的长度。
更新:
你的代码是正确的,除了一个小细节。 在对与fgets文档注意,将保持尾随的换行符字符。
为了解决这个问题,添加以下代码之间fgets
和strncmp
部分:
if ( guess[guessLen-1] == '\n' ) {
guess[guessLen-1] = '\0';
}
这样结尾的换行,如果有的话,被删除,你不再是关闭的一个。
的问题的一些列表/为您的代码意见,太长,以适应评论:
- 你的函数返回一个
char
是奇怪。 我不明白的逻辑和更重要的是,你实际上从来没有返回值。 不这样做,它会给你带来麻烦 - 看看其它控制结构中C,尤其是不要做你
exit
的事情。 首先, exit
在C是一个函数,它做什么它说,它退出程序。 再有一个break
语句退出循环。
一个常见的成语是
do {
if (something) break;
} while(1)
- 你在每次迭代中分配一个缓冲区,但你永远不
free
它。 这会给你很大的内存泄漏,缓冲区将被浪费,无法访问您的代码 - 您
strncmp
方法是唯一正确的,如果字符串的长度相同,所以你必须先测试
文章来源: Why is fgets() and strncmp() not working in this C code for string comparison?