Некоторые проблемы при кодировании «угадывания случайного числа в C» при некоторых условиях, таких как использование input (), output () - PullRequest
1 голос
/ 07 января 2020

Я пытался выйти за рамки простого угадывания случайных чисел. Условия были следующими:

  1. использовать input() числа, используемые от 1 до 100, и, если введенные числа находятся вне этого диапазона, показать строку для повторного ввода числа

  2. используйте output(), чтобы показать вывод (но покажите последнюю строку``` Вы получили его прямо с N-й попытки! "На main ())

  3. заставляет вставленный номер продолжать показываться на следующей строке.

По сути, программа должна быть настроена так:

insert a number : 70
bigger than 0 smaller than 70.
insert a number : 35
bigger than 35 smaller than 70.
insert a number : 55
bigger than 55 smaller than 70.
insert a number : 60
bigger than 55 smaller than 60.
insert a number : 57
You got it right on your 5th try!

I ' Я работаю над этим уже 6 часов ... (так как я новичок) ... и, к счастью, мне удалось получить структуру basi c, чтобы программа, по крайней мере, могла чтобы показать, больше ли число, чем вставленное число, меньше, чем введенное число.

Проблема в том, что я не могу получить числа, которые будут отображаться в строке. Например, я не могу вставленный номер 70 продолжает отображаться на smaller than 70.

Кроме того, я не могу узнать, как получить количество, сколько попыток было сделано. Сначала я попытался поместить его в input () как count = 0 ... count++;, но потерпел неудачу в выводе. Затем я попытался вставить в output (), но вывод не вернул count, поэтому я снова не смог.

Я надеюсь получить совет по этой проблеме.

Ниже приведен код, который я написал и который не содержит ошибок, но проблема в том, что он не соответствует условиям конечного результата. (Кстати, в настоящее время я использую Visual Studio 2017, поэтому есть строка #pragma warning (disable : 4996) и myflush вместо fflush.)

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)

int input();
int random(int);
void myflush();
void output(int, int);

int main()
{
    int num;
    int i;
    int ran;

    srand((unsigned int)time(NULL));
    i = 0;
    while (i < 1) {
        ran = 1 + random(101);  
        ++i;
    }

    num = input();
    output(ran, num);

    printf("You got it right on your    th try!");a

    return 0;
}

int input()
{
    int num;
    printf("insert a number : ");
    scanf("%d", &num);
    while (num < 1 || num > 100 || getchar() != '\n') {
        myflush();
        printf("insert a number : ");
        scanf("%d", &num);
    }
    return num;
}


int random(int n)
{
    int res;
    res = rand() % n;
    return res;
}

void myflush()
{
    while (getchar() != '\n') {
        ;
    }
    return;
}


void output(int ran, int num) {
    while (1) {
        if (num != ran){
            if (num < ran) {
            printf("bigger than %d \n", num);  // 
            }
            else if (num > ran) {
                printf("smaller than %d.\n", num);
            }
            printf("insert a number : ");
            scanf("%d", &num);
        }
        else {
            break;
        }
    }
    return;
}

Ответы [ 3 ]

2 голосов
/ 07 января 2020

В этом коде много проблем и возможных упрощений.

  • используйте fgets, чтобы прочитать строку, а затем scanf содержимое строки. Это устраняет необходимость в myflush, который не работает должным образом.
  • функция random не нужна, поскольку выбор случайного числа является простым выражением.
  • , если диапазон случайное число равно [1100], вы должны использовать 1+rand()%100.
  • , для функции output нет реальной необходимости, поскольку она является ядром основной программы. Однако функция input хороша для инкапсуляции ввода.
  • Вы должны проверить возвращаемое значение scanf, потому что ввод не всегда может содержать число.

Вот упрощенный код, обеспечивающий желаемый вывод.

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)

int input() {
    char line[100];
    int num, nVal;
    printf("insert a number : ");
    fgets(line, sizeof line, stdin);    
    nVal = sscanf(line, "%d", &num);
    while (nVal != 1 || num < 1 || num > 100) {
        printf("insert a number : ");
        fgets(line, sizeof line, stdin);    
        nVal = sscanf(line, "%d", &num);
    }
    return num;
}

int main()
{
    int cnt = 0, lowerLimit = 0, upperLimit = 101;

    srand((unsigned int)time(NULL));

    // pick a random number in the range [1,100]
    int ran = 1 + rand()%100;

    while(1) {
        cnt++;
        int num = input();
        if (num == ran)
            break;
        if (num > lowerLimit && num < upperLimit) {
            if (num < ran)
                lowerLimit = num;
            else
                upperLimit = num;           
        }
        printf("bigger than %d and smaller than %d\n", lowerLimit, upperLimit);
    }
    printf("You got it right on your %dth try!\n", cnt);
    return 0;
}
1 голос
/ 07 января 2020

Если вы хотите, чтобы программа всегда отображала самое высокое введенное число, которое меньше случайного числа («больше чем»), и самое низкое введенное число, которое больше случайного числа («меньше чем»), то ваша программа необходимо запомнить эти два числа, чтобы он мог обновлять и печатать их по мере необходимости.

В функции main вы можете объявить следующие два целых числа:

int bigger_than, smaller_than;

Эти переменные должны go войти в функцию main, потому что эти числа должны запоминаться на протяжении всей программы. Функция main является единственной функцией, которая выполняется для всей программы, все остальные функции работают только в течение короткого времени. Альтернативой было бы объявить эти две переменные глобальными. Однако это считается плохим стилем программирования.

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

Эти два целых числа должны быть переданы в функцию output каждый раз, когда она вызывается, увеличивая количество параметров этой функции с 2 до 4.

Если вы хотите, чтобы счетчик подсчитывал количество введенных чисел, вам также придется запомнить это значение в функцию main (или как глобальную переменную) и передайте ее функции output. Это увеличит количество параметров для функции до 5.

Если вы не хотите передавать столько параметров для вывода, вы можете объединить содержимое функций output и input в function main.

Однако в любом случае вам придется переместить большую часть «меньше чем» и «больше чем» logi c из функции output в функцию main, потому что эти логические значения c необходимы для изменения новых переменных типа "large_than" и "less_than", которые принадлежат функции main. Функция output должна содержать только фактические логи печати c.

Хотя технически возможно изменить эти две переменные, которые принадлежат функции main, внутри функции output, я полагаю не рекомендую, потому что это станет грязным. Вам потребуется передать несколько указателей на функцию output, что позволит этой функции изменять переменные, принадлежащие функции main.

. Теперь я написал свое собственное решение и обнаружил, что это гораздо проще написать, объединив функцию output в main. Я также объединил все остальные функции в main, но это было не так важно, как объединение функции output.

Вот мой код:

#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#pragma warning (disable : 4996)

int main()
{
    const char *ordinals[4] = { "st", "nd", "rd", "th" };
    int num_tries = 0;
    int bigger_than = 0, smaller_than = 101;
    int input_num;
    int random_num;

    srand( (unsigned int)time( NULL ) );
    random_num = 1 + rand() % 101;

    for (;;) //infinite loop, equivalent to while(1)
    {
        printf( "Bigger than: %d, Smaller than: %d\n", bigger_than, smaller_than );

        printf( "enter a number: " );
        scanf( "%d", &input_num );
        printf( "You entered: %d\n", input_num );

        num_tries++;

        if ( input_num == random_num ) break;

        if ( input_num < random_num )
        {
            if ( bigger_than < input_num )
            {
                bigger_than = input_num;
            }
        }
        else
        {
            if ( smaller_than > input_num )
            {
                smaller_than = input_num;
            }
        }
    }

    printf( "You got it right on your %d%s try!", num_tries, ordinals[num_tries<3?num_tries:3] );

    return 0;
}

Также я удостоверился, что программа напечатает «1-й», «2-й» и «3-й», тогда как все другие решения просто напечатают «1-й», «2-й», «3-й». Для этого я использовал условный оператор c ++.

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

Я не могу узнать, как узнать количество попыток.

Измените функцию output с void на int, чтобы она может вернуть значение для count и записать комментарии для других изменений:

int output(int ran, int num) {//changed from void to int
    int count = 0;//create a variable to track tries
    while (1) {
        if (num != ran){
            count++;//increment tries here and...
            if (num < ran) {
                printf("bigger than %d \n", num);  // 
            }
            else if (num > ran) {
                printf("smaller than %d.\n", num);
            }
            printf("insert a number : ");
            scanf("%d", &num);
        }
        else {
            count++;//... here
            break;
        }
    }
    return count;//return value for accumulated tries
}

Затем в main:

//declare count
int count = 0;
...
count = output(ran, num);
printf("You got it right on your %dth try!", count);

С этими изменениями ваш код работал так, как вы описали выше.
(Однако th работает не так хорошо, хотя для 1-й, 2-й или 3-й попытки)

...