0

以下に貼り付けたコードに問題があり、実行時にハングします。VS2010 では、警告やエラーは表示されません。

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


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

int validate(int low, int high) {
    int num;

    scanf("%d", &num);
    while(num < low || num > high) 
    {
        clear_buffer();
        printf("INVALID! Must enter value between %d and %d: ", low, high);
        scanf("%d", &num);
    }
    return num;
}

int getRand(int max) {
    int number;
    number = rand() % max + 1;
    return number;
}

int validatePick(int pick, int one, int two, int three, int four, int five) {
    int valid = 0;

    if (pick != one && pick != two && pick != three && pick != four && pick != five) {
        valid = 1;
    } else {
        valid = 0;
    }
    return valid;
}
void prnt(int qty, int one, int two, int three, int four, int five, int six) {
    int i = 0, flag = 0;
    while (flag != 2) {
        flag = 0;
        if (sort2(&one, &two) == 0 && sort2(&three, &four) == 0 && sort2(&five, &six) == 0)
            flag = 1;
        if (sort2(&two, &three) == 0 && sort2(&four, &five) == 0)
            flag = 1;
        flag += flag;
    }

    printf("Picks: %d, ", one);
    while (i <= qty){
        if (i== 2 && qty == 2)
            printf("%d\n", two);
        else if (i == 2 && qty != 2) 
            printf("%d, ", two);

        if (i == 3 && qty == 3) 
            printf("%d\n", three);
        else if (i == 3 && qty != 3) 
            printf("%d, ", three);

        if (i == 4 && qty == 4)
            printf("%d\n", four);
        else if (i == 4  && qty != 4)
            printf("%d, ", four);

        if (i == 5 && qty == 5)
            printf("%d\n", five);
        else if (i == 5  && qty != 5) 
            printf("%d, ", five);

        if (i == 6 && qty == 6) 
            printf("%d\n", six);
        i++;
    }
}



int sort2(int *n1, int *n2) {
    int tmp, valid = 0;

    if (*n1 > *n2)
    {
        tmp = *n2;
        *n2 = *n1;
        *n1 = tmp;
        valid = 1;
    }
    return valid;
}

int main () {
    int num1, num2;
    int pick, one = 0, two = 0, three = 0, four = 0, five = 0, six = 0;

    srand(time(NULL));

    printf("LOTTERY GENERATOR\n");
    printf("Enter the maximum value between 1 and 100: ");
    num1 = validate(2,100);
    printf("Enter quantity of numbers to pick, between 1 and 6: ");
    num2 = validate(1, 6);

    one = getRand(num1);
    while (two == 0 || three == 0 || four == 0 || five == 0 || six == 0) {
        pick = getRand(num1);
        if (validatePick(pick, one, two, three, four, five) == 1 && two == 0)
            two = pick;
        else if (validatePick(pick, one, two, three, four, five) == 1 && three == 0)
            three = pick;
        else if (validatePick(pick, one, two, three, four, five) == 1 && four == 0)
            four = pick;
        else if (validatePick(pick, one, two, three, four, five) == 1 && five == 0)
            five = pick;
        else  if (validatePick(pick, one, two, three, four, five) == 1)
            six = pick;
    }
    prnt(num2, one, two, three, four, five, six);
}

3 と入力してEnter the maximum value between 1 and 100から 2 と入力すると、プログラムがハングします。なぜそんなことをするのか理解できません。コードにエラーはありません。何か案は?

4

2 に答える 2

5

問題はあなたの論理にあると思います。1プログラムを正しく理解していれば、 からまでの範囲でランダムに生成された 6 つの異なる数字を選択しようとしていnum1ます。

問題は次のとおりです。whileループは、6 つの変数 ( onetwo.. six) がすべて ではない場合にのみ終了します0。これらの変数の 1 つをゼロ以外の値に設定できる唯一の方法は、validatePickが返される場合1であり生成された乱数がonetwo...のいずれかにまだ割り当てられていない場合にのみ発生しますsix

これは、逆ピジョンホール問題のようなものに要約されます。6 つ未満の鳩で 6 つの鳩の穴を埋めようとしていますが、これは不可能な作業です。

num1が より小さい場合、6while ループの終了条件を満たすことは不可能であり、プログラムは一見ハングアップします。

これを確認するには、while ループにケースを入れて、else生成した乱数を出力し、各反復で各変数の値を出力します。

2 番目の入力 はnum2、ループが終了するまで参照されないことに注意してください。whileそのため、そこに入力した値は、プログラムが生成しようとする一意のランダム値の数を制限することはできません。

于 2012-11-07T02:34:01.210 に答える
0

これはおそらくバッファリングによるものです。3が入力された場合、チェックはパスし、clear_buffer呼び出されないことに注意してください。入力後でも呼び出されるように関数を変更してみてください。

これが私があまり好きではない理由ですscanf-- バッファの状態を見失い、プログラムがループに陥ってしまうのは簡単です。私は、たとえば を使用して行全体を読み取り、fgetsトークン化して自分で解析することを好みます。このような単純なプログラムの場合、strtolまたは を使用するだけでも非常に簡単atoiです。少なくともこのようにして、入力の多くのエッジケースすべてをより直接的に可視化できます。

于 2012-11-07T02:28:46.877 に答える