C:rand()和scanf()故障?

时间:2014-10-29 12:53:49

标签: c

我对C / C ++有些新意,我在下面的代码中没有得到我的问题。 在这个赋值中,我被限制只使用C函数和语法,不允许使用C ++。

程序应该从字母表中选择一个随机字符,并让用户3尝试猜测它。

#include <stdio.h>
#include <stdlib.h>
#define guesses 3

int main(){

    setbuf(stdout, NULL);
    /* A 2.P.b */

    /* version with loop*/

    int i = 0;
    char randomChar = (65 + (rand()%26) + 1);

    /* comment the line below, when the programm works as intended */
     printf("\n%c\n", randomChar);

    char guessedChar;

    while((i<=guesses) && (guessedChar != randomChar)){

        printf("Guess a letter.\n");
        scanf("%c", &guessedChar);

        if(guessedChar != randomChar){
            int guessesLeft = guesses - i;
            if (guessesLeft > 1){
                printf("Wrong letter. You have %d more tries.\n", guessesLeft);
            }
            else{
                printf("Wrong letter. Last try.");
            }

        }

        else{
            printf("Congratulations.\n");
        }

        i++;
    }
    return 1;
}

输出如下:

Q
Guess a letter.
A
Wrong letter. You have 3 more tries.
Guess a letter.
Wrong letter. You have 2 more tries.
Guess a letter.
B
Wrong letter. Last try.Guess a letter.
Wrong letter. Last try. 

问题:

所选字母不是随机的,但总是Q.

第一个猜测需要花费两倍的成本&#34;生活&#34; ?!

6 个答案:

答案 0 :(得分:1)

可能你总是得到Q因为你没有为发电机播种。尝试添加

srand ( time(NULL) );

在生成它之前。

答案 1 :(得分:1)

scanf的问题是你输入的字母后面的换行符仍然留在输入缓冲区中,并会在下一次读取。

要解决此问题,只需告诉scanf通过在格式字符串中添加单个空格来读取和跳过所有前导空格,例如

scanf(" %c", &guessedChar);
//     ^
//     |
//     Note space here

随机数生成的问题在于您不为种子生成种子,这意味着它始终以相同的种子开始并始终生成相同的数字。

要设置种子,需要在调用srand之前调用rand函数,这是一个不可预测的种子(当前时间通常已足够):

srand(time(NULL));

然而,有一个更严重的问题,那就是你在初始化之前使用guessedChar。这将导致undefined behavior,因为未初始化的非静态局部变量具有不确定的值。您必须在使用它们之前初始化本地(非静态)变量,并且对未初始化的变量的唯一有效用途是初始化它。

答案 2 :(得分:0)

您需要在srand开头使用main获取随机字母(不要忘记包含time.h!)

srand(time(NULL));

至于scanf的问题,请在%c中的scanf之前添加空格:

scanf(" %c", &guessedChar);

这样做是为了删除在您输入字符后输入字符时\n中出现的stdin,并在输入字符后按Enter键。

答案 3 :(得分:0)

当然。 rand()生成伪随机数。对于像这样的许多目的来说,它足够随机。但是,您必须更改起点,否则您将始终获得相同的数字。 你应该拨打srand(something);,对于某些东西,你可以替换任何一个号码,这样你就可以有很多记住的游戏&#34;游戏&#34;或者你可以按当前时间(包括毫秒)初始化,这将是非常难以理解的可重复的。

#include <time.h>       /* time */

int main(){
srand (time(NULL));
...

答案 4 :(得分:-1)

实际上rand()实际上并不是随机的,因为它从固定数组中获取数字,所以每次调用rand()时都会得到相同的数字,所以使用相同的等式,你将得到相同的字符,然后用于首先猜测,你正在测试得到答案,这就是为什么你应该使用

do
{
}
while ();

而不是

while()
{
}

答案 5 :(得分:-3)

如果您只是输入一个字符,请尝试使用

getch();

而不是

scanf(...);

do

{
}
while ();

而不是

while()
{
}

因为你接受了答案然后你就做了测试...