为什么与fgets()和STRNCMP()在字符串比较这个C代码不工作?(Why is fgets(

2019-09-20 14:05发布

这是我遇到了一个非常有趣的问题。 我做了很多的堆栈溢出搜索,发现其他人有一些类似的问题。 所以我写了相应的我的代码。 我本来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

Answer 1:

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) 这种速战速决的问题是,它会通过无效输入,也就是说,如果wordeject ,并guessejection ,比较会通过。

最后,没有理由来分配内存为新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: ");
        // ...


Answer 2:

使用strlen ,不是sizeof 。 此外,你不应该使用strncmp这里,如果你的猜测是,这个词会误报匹配的前缀。 使用strcmp



Answer 3:

正如其他人所指出的,使用strlen不是sizeof 。 这虽然发生的原因,是一个基本概念C这是从不同Java

Java不给你访问的指针 。 不仅C有一个指针,但他们的语言设计的基础 。 如果你不理解和正确使用指针C那么事情就没有意义,你将有相当多的麻烦。

因此,在这种情况下, sizeof被返回的大小char *指针,它是(通常)4或8个字节。 你需要的是数据结构“的另一端”指针的长度。 这是strlen封装为您服务。

如果你没有strlen ,你需要取消引用指针,然后步行串,直到找到空字节标记结束。

i = 1;
while(*guess++) { i++ }

之后, i会牵着你的字符串的长度。

更新:

你的代码是正确的,除了一个小细节。 在对与fgets文档注意,将保持尾随的换行符字符。

为了解决这个问题,添加以下代码之间fgetsstrncmp部分:

if ( guess[guessLen-1] == '\n' ) {
    guess[guessLen-1] = '\0'; 
}

这样结尾的换行,如果有的话,被删除,你不再是关闭的一个。



Answer 4:

的问题的一些列表/为您的代码意见,太长,以适应评论:

  • 你的函数返回一个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?