Reputation: 453
I'm having issues with the code pasted below where it just hangs during runtime. VS2010 doesn't give me any warnings or errors.
#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);
}
If I enter say 3 for Enter the maximum value between 1 and 100
and then 2 the program just hangs. I don't understand why it does such. I don't see an error in the code. Any ideas?
Upvotes: 0
Views: 137
Reputation: 5181
I think the problem is in your logic. If I understand the program correctly, you are trying to pick 6 different numbers, randomly generated in the range from 1
to num1
.
Now here's the problem: Your while
loop only terminates when all six variables (one
, two
.. six
) are not 0
. The only way that one of these variables can be set to a non-zero value is if validatePick
returns 1
, and that can only happen if the random number generated has not already been assigned to one of one
, two
... six
.
This boils down to something like a reverse pigeon-hole problem; you are trying to fill six pigeon-holes with less than six pigeons, an impossible task.
If num1
is less than 6
, then its impossible for you to satisfy the termination condition of your while loop, and your program will seemingly hang.
You can verify this by putting an else
case in your while loop and printing what random number you generated, and also printing what the value for each variable is at each iteration.
Note that your second input, num2
, is not referenced in any way until after your while
loop, so the value you enter there will not be able to limit the number of unique random values your program tries to generate.
Upvotes: 5
Reputation: 10819
This is likely due to buffering. Note that if 3
is entered, the check passes and clear_buffer
is not called. Try changing the function so that it's called after the input even.
This is why I don't like scanf
so much -- it's so easy to lose track of the state of the buffer, and find your program stuck in a loop. I prefer to read a whole line, using, say, fgets
, then tokenise it and parse it myself. For a simple program like this it's pretty easy using strtol
or even just atoi
. At least this way I have more direct visibilty of all the many edge-cases of input.
Upvotes: 0