Странный цикл во время сканирования - PullRequest
0 голосов
/ 10 марта 2019

Я написал этот код. Он должен прочитать целое число от 1 до 4 (определяется как нижняя и верхняя границы функции), и если условие не выполняется, выводит некоторое сообщение об ошибке и снова задает вопрос.

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

int varcheck(double x, char z, int lowerbound, int upperbound);

int main(){

    double playerCount;
    char i;

    printf("Insert Number of Players: ");
    scanf("%lf%c", &playerCount, &i);

    while(varcheck(playerCount, i, 1, 4) == 0){
        printf("Invalid Number of Players\n");
        printf("Insert Number of Players: ");
        scanf("%lf%c", &playerCount, &i);
    } 
    // ...Code continues...
}




int varcheck(double x, char z, int lowerbound, int upperbound){
    double r = 0;
    r = x - (int)x;  /*If r == 0 then its not decimal number*/ 

    if(r != 0 || z != '\n' || x < lowerbound || x > upperbound){
        return 0;
    } else {
        return 1;
    }
}

Функция входит в какой-то странный цикл, кто-нибудь может мне помочь исправить это?

Ответы [ 2 ]

1 голос
/ 10 марта 2019

Ну, во-первых, этот код - полный беспорядок, через который надо охотиться.

  1. Вы не завершили ни одного цитируемого раздела (в printf с и scanf с)
  2. Нет отступа
  3. Использование double для playerCount
  4. И поскольку это double, его значение может быть примерно таким, как 12.000001, и, следовательно, r может никогда не быть 0.
  5. Я бы предложил использовать getchar вместо scanf, когда вам нужно проанализировать такие символы, как \t, \n и "" (пробел).
  6. Я бы сказал, проверьте этот раздел еще раз: x < lowerbound || x > upperbound, потому что я думаю, что вы намеревались сделать это: x > lowerbound || x < upperbound

Исправьте эти проблемы, и ваш код должен работать нормально, я думаю. Однако отступ не имеет ничего общего с точностью.

0 голосов
/ 10 марта 2019

Функция scanf немного сложна для анализа пользовательского ввода. Одна проблема заключается в том, что scanf оставляет входной поток нетронутым / неизменным, если он не может проанализировать запрашиваемый вами объект. Пример - если вы введете «aaa2» и попытаетесь найти поплавок, scanf даст нулевые результаты, а входной поток все еще будет содержать «aaa2». Следовательно, следующий scanf также увидит данные "aaa2" и у вас будет бесконечный цикл.

Решением является очистка входного потока при сбое преобразования. Это может быть что-то вроде этого:

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

void flushInput()
{
    // Keep reading from input stream until a newline is read
    int c;
    do
    {
        if ((c = getchar()) == EOF) exit(1);
    } while (c != '\n');
}

int getInt()
{
    int n;
    char c;
    while(1)
    {
        // scanf will return 2 if the conversion is succesful, i.e.
        // if it could scan first an integer and then a character
        if (scanf("%d%c", &n, &c) == 2 && c == '\n') return n;

        // Conversion failed so flush the input stream
        flushInput();
    }
}

int main(void) {
    int n;
    int lowerbound = 1;
    int upperbound = 4;
    do
    {
        n = getInt();
    } while (n < lowerbound || n > upperbound);
    printf("n=%d\n", n);
    return 0;
}

Введите:

4.2

aaaa2
9
3a
2

Выход:

n=2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...