2014-10-29 2 views
-1

Я немного новичок в C/C++, и я не понимаю, что моя проблема в следующем коде. В этом задании я ограничен только для использования C-функций и синтаксиса, C++ не допускается.C: неисправность rand() и scanf()?

Программа должна выбрать случайный символ из алфавита и дать пользователю 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.

Первое предположение требует затраты двух «жизней «?!

+1

Два вопроса в одном. Оба дубликата. http://stackoverflow.com/questions/8724582/rand-not-generating-random-numbers-after-modulo-operation http://stackoverflow.com/questions/3744776/simple-c-scanf-does-not-work –

+3

Вы ** прочитали документацию ** из [rand (3)] (http://man7.org/linux/man-pages/man3/rand.3.html) и [scanf (3)] (http : //man7.org/linux/man-pages/man3/scanf.3.html), как и следовало бы? Если бы вы это сделали, вы не стали бы задавать вопрос. Также попробуйте понять, что означает RTFM и STFW. и компилировать со всеми предупреждениями и информацией об отладке 'gcc -Wall -Wextra -g') BTW, C & C++ - * разные языки * –

+0

и, возможно, GIYF и LMGTFY для менее менее оскорбительных альтернатив по тем же линиям. – bph

ответ

1

Проблема с scanf заключается в том, что новая строка после введенной буквы все еще остается во входном буфере и будет читаться в следующий раз.

Чтобы решить эту проблему просто сказать scanf читать и пропустить все ведущие пробелы, добавив один пробел в строке формата, как

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

Проблема генерации случайных чисел является то, что вы не» t запустит генератор, что означает, что он всегда будет начинаться с одного и того же семени и всегда генерировать одинаковый номер.

Для установки семян необходимо вызвать функцию srand перед вызовом rand, который не-предсказуемы семян (текущее время обычно достаточно):

srand(time(NULL)); 

Существует, однако, гораздо больше, серьезная проблема, и это то, что вы используете guessedChar перед его инициализацией. Это приведет к undefined behavior, поскольку неинициализированные нестатические локальные переменные имеют неопределенное значение. Вы должны инициализировать локальные (нестатические) переменные, прежде чем использовать их, и единственное допустимое использование неинициализированной переменной - инициализировать ее.

+0

большое спасибо! :) – Alex

1

Возможно, вы всегда получаете Q, потому что вы не засеваете генератор. Попробуйте добавить

srand (time(NULL)); 

перед его созданием.

0

Вы должны использовать srand в начале main для случайных алфавитов (Не забудьте включить time.h!)

srand(time(NULL)); 

А что касается проблемы с scanf, добавьте пробел перед %c в scanf :

scanf(" %c", &guessedChar); 

Это делается для удаления \n, который будет присутствовать в stdin после вас введите символ при нажатии клавиши ввода после ввода символа.

0

Конечно. rand() генерирует псевдослучайное число. Это достаточно случайно для многих целей, подобных этому. Однако вам нужно изменить начальную точку, иначе вы всегда будете иметь одинаковые номера. Вы должны позвонить srand(something); и за что-то, вы можете заменить любое число, которое позволит вам иметь много запоминающихся знающих «игр», или вы можете инициализировать это по текущему времени (в том числе miliseconds), что будет очень непростительно повторяемо.

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

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

На самом деле рандов() является нт действительно случайным, так как он получает номер от фиксированного массива, поэтому каждый раз, когда вы звоните RAND() вы получаете тот же номер, так с тем же уравнением вы собираетесь получить тот же характер , то за первое предположение, вы тестируете Befor получать ответ, почему вы должны использовать

do 
{ 
} 
while(); 

вместо

while() 
{ 
} 
+0

Функция ['rand'] (http://en.cppreference.com/w/c/numeric/random/rand) не использует фиксированный массив. –

+0

Пожалуйста, используйте опцию «удалить», чтобы удалить ответ. –

-3

если вы только принимая характер на входе, т чень использовать

getch(); 

вместо

scanf(...); 

и

do 

{ 
} 
while(); 

вместо

while() 
{ 
} 

, поскольку вы берете ответ, то вы делаете тест ...

+0

получите характер! getch! – indian