Угадай секретный номер человека от 0 до 100, используя бинарный поиск - PullRequest
1 голос
/ 14 января 2020

Я конвертировал код, который я знаю, как создать на python на C языке, но каждый раз, когда я запускаю программу в CodeBlocks, программа вылетает! И я понятия не имею, почему это происходит, кто-то может мне помочь?

Предполагается, что программа угадывает номер человека (от 0 до 100), используя бинарный поиск. Например, если мое число равно 66, программа спрашивает, является ли мое число 50, поскольку 66 больше 50, число 50 становится нижней границей, а 100 остается верхней границей, и так далее ...

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    int x;
    printf("Please think of a number between 0 and 100\n\n");
    x = binarysearch();
    printf("%d", x);


}
int binarysearch()
{
int hi,lo,guess;
hi = 100;
lo = 0;
char user_inp;
while (1){
    guess = round(((hi + lo)/2));
    printf("Is your secret number %d?\n\n", guess);
    printf("Enter 'h' to indicate the guess is too high. \nEnter 'l' to indicate the guess is too low.\nEnter 'c' to indicate I guessed correctly. \n");
    scanf("%c", &user_inp);
    if (strcmp(user_inp, "c") == 0){
        break;
    }
    else if  (strcmp(user_inp, "h")==0){
        hi = guess;
    }
    else if (strcmp(user_inp, "l")==0){
        lo = guess;
    }
    else{
        printf("Sorry, I did not understand your input.");
        continue;
    }
}
printf("Game over. Your secret number was");
return guess;

}

Ответы [ 2 ]

1 голос
/ 14 января 2020

Согласно комментариям, проблема, вероятно, заключалась в неправильном использовании strcmp:

char *string = "fish";
char not_a_string = 'f';
if (0 == strcmp( not_a_string, string  ))
  ...

Символ 'f' имеет значение ASCII 0x66. strcmp будет слепо использовать это как указатель (ожидая, что он укажет на допустимую строку), что вызовет cra sh при доступе к не вашей памяти ( ошибка сегментации ).

В этом случае вам не помешает strcmp( &not_a_string, string ), но это удача, а не правильный код.

Чтобы сравнить вводимые пользователем символы с другим символом, вы можете просто использовать прямое равенство (так как оба они на самом деле целые):

if ( user_inp == 'c' ) ...

Итак, это ваш код исправлен, но как вы вообще смогли его запустить? Для меня G CC сразу же пожаловался:

In function 'int binarysearch()': so.cpp:17:29: error: invalid conversion from 'char' to 'const char*' [-fpermissive] 
if (strcmp(user_inp, "c") == 0){

и не дал вывода. Это говорит вам то же самое, что я только что сделал (хотя и немного более загадочно).

Уроки, которые нужно выучить: выслушать жалобы вашего компилятора (и сделать ваш компилятор как можно более жалобным)


@pmg также отметил:

добавить пробел перед спецификатором преобразования: scanf(" %c", &user_inp)

Без него при каждом нажатии Enter:

Sorry, I did not understand your input.Is your secret number 25?

ie Вы получаете ложную жалобу. Но с пробелом все работает как надо.

(я ненавижу scanf, поэтому понятия не имею, почему это работает;))

1 голос
/ 14 января 2020
  1. Ваш двоичный поиск неверен, вам нужно поменять чек на 'h' и 'l'.
  2. Поскольку вы сравниваете символы, а не строки, используйте ==, а не strcmp().
  3. Вам не нужно включать <math.h>, потому что угадайте int, поэтому оно будет автоматически округлять числа с плавающей точкой.
  4. Вы можете использовать getchar() для очистки буфера после scanf()
  5. Вам необходимо объявить вашу функцию до main (возможно, определив функцию до main).
#include <stdio.h>
#include <stdlib.h>
// WITHOUT <MATH.H>

int binarysearch(void);

int main(void)
{
    int x;
    printf("Please think of a number between 0 and 100\n\n");
    x = binarysearch();
    printf("%d", x);
    return 0;    // RETRUN 0    
}

int binarysearch(void)
{
    int hi,lo,guess;
    hi = 100;
    lo = 0;
    char user_inp;
    int flag = 1;    // USE FLAG, NOT BREAK AND CONTINUE
    while (flag){
        guess = ((hi + lo)/2);   // WITHOUT ROUND
        printf("Is your secret number %d?\n\n", guess);
        printf("Enter 'h' to indicate the guess is too high. \nEnter 'l' to indicate the guess is too low.\nEnter 'c' to indicate I guessed correctly. \n");
        scanf("%c", &user_inp);
        getchar(); // CLEAR THE BUFFER
        if (user_inp == 'c'){   // MAKE FLAG 0
            flag = 0;
        }
        //  USE '==', NOT STRCMP
        else if  (user_inp == 'l'){  // YOU NEED TO SWAP 'L' & 'H'
            hi = guess;
        }
        else if (user_inp == 'h'){
            lo = guess;
        }
        else{
            printf("Sorry, I did not understand your input.");
        }
    }
    printf("Game over. Your secret number was ");
    return guess;
}
...