2

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

4 回答 4

4

使用strlen,不使用sizeof。另外,你不应该strncmp在这里使用,如果你的猜测是单词的前缀,它会错误地报告匹配。使用strcmp.

于 2012-07-31T19:32:09.177 回答
2

sizeof(guess)正在返回 a 的大小而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保留了换行符,因此如果要比较这两个单词,则需要考虑这一点。一个快速解决方法是只比较 的长度,而不是 的长度,所以:。这个快速修复的问题是它会传递无效的输入,即如果is和is ,比较就会通过。wordguessif( strncmp(guess, word, wordLen) == 0)wordejectguessejection

最后,没有理由guess在循环的每次迭代中为 new 分配内存,只需使用您已经分配的字符串。您可以将功能设置更改为:

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: ");
        // ...
于 2012-07-31T19:34:09.613 回答
2

正如其他人所说,使用strlennot 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'; 
}

这样,尾随的换行符(如果有)将被删除,并且您不再落后一个。

于 2012-07-31T19:44:57.440 回答
1

您的代码的一些问题/建议列表,太长了,无法放在评论中:

  • 你的函数返回一个char很奇怪的。我看不到逻辑,更重要的是,您实际上永远不会返回值。不要那样做,会给你带来麻烦
  • 查看 C 中的其他控制结构,特别是不要做你exit的事情。首先,exit在 C 中是一个函数,它执行它所说的,它退出程序。然后有一个break语句离开一个循环。

一个常见的成语是

do {

   if (something) break;
} while(1)
  • 你在每次迭代中分配一个缓冲区,但你从来没有free。这会给你带来很大的内存泄漏,缓冲区将被浪费并且你的代码无法访问
  • 只有当字符串具有相同的长度时,您的strncmp方法才是正确的,因此您必须先对其进行测试
于 2012-07-31T20:22:43.560 回答